Re: Creating a "toy" OO/AO language...
I think I'll widen the audience a little bit.
On Oct 1, 1:57 pm, Daniel Pitts <googlegrou...@coloraura.com> wrote:
This isn't really a question as much as a request for opinions/
comments.
I've decided to create a toy OO language. I know, there are plenty of
good wheels, but I like to reinvent them anyway...
I'm creating this language to solve a meta-problem when designing
interactive fiction (text based adventure) games. The language itself
isn't specific to this problem, but the design decisions are biased
toward that end.
Brain dump of features, sorry if its a little disorganized.
* Named Instances: Somewhat like singletons, a named instance can
be created without any express instantiation.
* Dynamic typing: While I think strong-typing prevents simple
errors, its not as useful when you have a lot of AOP at play. Knowing
that most things implement the method "isFlammable()" should be good
enough.
* NULL value is a named instance. It has no-op behavior and
resists all modifications.
* Instances and Types (Maybe called classes?) can be modified at
runtime. New methods/fields can be added, and old methods/fields
overwritten.
* Methods are "special" object with an associated instruction list.
* Three kinds of instruction lists:
* Lambda. Lambda match up to traditional methods. "return"
instructions leave the inner most lambda where they're defined (not
execute from).
* Control. Used in control structures where "break" and
"continue" make sense. break and continue do what you would expect
with regards to the inner-most Control instruction list. I'll
probably also handle named control-points.
* Scope. Used simply to provide a named scope, or grouping of
instructions. Useful for if/else handling.
* Methods are actually Message Handlers.
* Before a method's instruction list is interpreted, a Message
instance is created with a target (aka this), a name (aka, the method
name), and a parameter instance (named parameters).
* If an instance has a member called "dispatchMessage", it will
be passed the message instance, otherwise the member corresponding to
"name" will be passed the message. if "name" is the NULL instance,
then the instruction list associated with the "this" instance is
executed instead.
* Member lookup:
* Raw lookup: Instances internally are a map of Instance->Instance. The raw lookup will access this map directly. Raw lookup
is used internally in very few specific places.
* soft lookup: Raw lookup is used to find the member "lookup".
If "lookup" is NULL, raw lookup is used to find the asked for member.
Otherwise lookup is invoked with the message {name: "lookup",
parameters {name: memberName}. while in the lookup method, all
lookups on the current object are raw.
* Control structures
* Boolean typed instances named True and False implement method
dispatchTruth, which dispatches either "true()" or "false()" on the
target object. if/else syntax will use this mechanism: if(a) {b} else
{c} would end up being a.dispatchTruth({true() { b } false() {b}});
* while/for syntax create a (natively implemented for now) Loop
instance:
* for (a;b;c) {d;} -> Loop.execute({initialize: { a }
condition: $lambda{ b } each: $control {d} afterEach: {c}});
* for-each/do supported.
* hooks for beforeFirst, afterFirst, beforeLast, afterLast,
beforeNotFirst, afterNotFirst, beforeNotLast, afterNotLast.
* beforeCondition hook for "primed" loops. (useful in some
algorithms)
* String constants
* "String Constants", 'String constant', and >>> \nmulti-line
\nstring comments <<<. (replace \n with actual cr)
* Standard "concat" operator (I think #)
* C++ style comments (//, /* */)
* Non-primative numerics.
* Behavior can be added to numeric values. Expression evaluation
is actually messages (with some default native handlers)
* Instance references for all Named instances will be fulfilled at
startup, before any behavior is invoked.
* Entry Point:
* A named instance (provided on the command line) is the entry
instance.
* The "main" method is invoked with command line arguments. If
arguments in the form of "a=b", then the parameter instance has field
'a' set to value "b".
* Operator's ('+', '-', '*', '/', '[]', '#', '()', etc...) have
conventional precedence, and convert to same-named methods. '#' is
defined to imply appending, either concatinating a string, or adding
to the end of a list.
I can't think of anything else now...
Oh, right, I do plan on having some form of inheritance or easy-to-
define delegation, but I haven't worked that out yet. perhaps
something like: (foo,bar,someOtherMemberDelegated)->delegateInstance.
Same named fields pointing to two delegates would create a list that
dispatches messages to both delegate instances.
Anybody have any thoughts, warnings, advice, concerns, excitement, or
boredom relating to this? It's not designed to be fast right now, one
of my goals is to enable easy implementation of good OO/AO design. If
I can achieve this goal, then I'll worry about efficiencies.
Thanks,
Daniel.