proj-oot-ootSyntaxNotes2

Difference between revision 28 and current revision

No diff available.

we want to be able to declare some functions as associative, etc. Perhaps it would be best if, just like we want operator precedence to be easily readable based on the symbols used, we make some conventions for things like associativity too? some ideas:

symmetric multichar ops with even # of chars are commutative and/or symmetric ops with +, * are assoc, ops with -, / are the inverses of the comparable +, * ops with = are reflexive, transitive, comparison ops and if not. symmetric and contains only one of <,> then are antisymmetric (note: antisymmetry seems like it may mean that either such operators operate directly, not on equivalence classes, or that equivalence must be redefined whenever these are; do we want that? seems too complicated, this link between different operators. otoh hand, if you just make sure that neither <= nor >= holds within an equivalence class, you're good, so mb this is ok (later: did i mean < and > within the class?)) ops with < or > are transitive does 'with' mean starting with?? startting with or ending with? or, ( starting AND ending) OR (oddnumbered and middle character)

with these rules, ++ would be commutative. so 'append' cant be ++. so would really like to make addition ++, and make '+' append.

hmm.. but otoh that's the kind of thing that ppl would forget if they are away from the language for awhile.

also, initially i was thinking this would save us some syntax as we could not have any other way to declare things associative, commutative, etc, but now i think that's too implicit.

---

maybe the language would be simpler without variadic args? or does it not matter if we already have defaults?

---

if we use ' for exception/maybe/option/nullableTypes tower wrapping/unwrapping, then we can't use it for quoting string literals ('hello'), or for a shortcut for keywords or quoting ('hello)

it's unclear whether it would be better to use ' for strings and use " for something else, or to use ' for the maybe tower

---

need a convenient per-argument syntax for strict, recursive strict, lazy annotations

---

review the old pseudo-oot in [1]

---

Haskell: difference between . (compose functions) and $ (sorta like pipe, but with order reversed)

http://stackoverflow.com/questions/940382/haskell-difference-between-dot-and-dollar-sign

---

i go back and forth on this, but currently i feel that there should be a maximum limit on non-keyword (positional) arguments in called functions, perhaps 3. This is to make code easier to read. However, this requires us to have a separate syntax for keyword arguments and defaultable arguments, unlike Python. The obvious syntax is 'x/ ' for a defaultless keyword argument.

(note: why 3? http://en.wikipedia.org/wiki/Arity and a quick Google search for the terms 'ternary function' and 'quaternary function' convinced me that 3-ary is the last common one)

---

general form for ternary operators: arg1 ?arg2? arg3 where '?' is some punctuation character, possibly custom defined

(or, should we permit only matching delimiters for this, eg arg1 <arg2> arg3)

---

want auto initializers like in C++, so you don't have to do the tedious thing you have to do in Python:

class C(): def __init__(param1, param2): self.param1 = param1 self.param2 = param2

---

similarly, when you are composing a class from multiple superclasses, sometimes upon some method being called, you need to call ALL of the superclasses implementations of this method (or at least, the methods from those superclasses which 'care') e.g.

class A(): def idle(self): do_important_thing_1()

class B(): def idle(self): do_important_thing_2()

class C(A, B): def idle(self): A.idle(self) B.idle(self)

would be nice to have language support for this to reduce the tedium of writing C's idle(), while also making it less error-prone (eg forgetting to change the implementation of C.idle when you swap-in/swap-out various superclasses; imagine that each class has 20 things like idle(), now you see how one or two could get messed up)

---

in fact, class construction from methods, class construction via inheritance, class construction via composition, class construction via auto-calling all relevant superclass methods from each method as noted in the previous section, could all be just operators, e.g. functions taking classes (and other parameters, such as lists of methods) to classes. This allows new custom class construction operators. As opposed to only having language support for one or two ways of creating classes, e.g. Python (although in Python you could easily make 'class operators' too, and you also have metaclass programming in Python)

---

could make it mandatory that if there are two vars in the same scope, and one's name is of the form "x", and the other "xs", that the latter's type is a list or graph of the former

and/or, this could have something to do with automapping lists; eg even if 'x' is an automapping list, then 'xs' disables the automapping

should all lists be automapping by default?

---

i'm thinking of using $x instead of ?x for metavariables. $ would still be interpolation. This would also be antiquote. So in general, '$' would mean that something is 'more of a variable' than the default in its context; in the ordinary code context, where identifiers are already variables, it's a metavariable; in the context of a non-raw string, $ means interpolation; in the context of a quote, $ is antiquote; in the context of a type signature, $x is a type variable.

(i feel that giving type variables a variable-indicating sigil prefix will be easier for newbies to grok than Haskell's way of just having lowercase identifiers which are assumed to be variables rather than constant types)

---

i like how AtScript? specifies a syntax but not a semantics for types

---

i dislike how AtScript? uses list<int> for generics. Generics are just type functions. Use 'list int'.

---

Haskell-ish @atbinding seems useful. The idea is that you put that within a pattern expression, and it lets you bind the subexpression at that point in the AST to a value.

We should support this both for pattern expressions (type expressions) and also for ordinary value computations.

---

AtScript? and Python use @annotation for annotations. i think this is what we'd use UPPERCASE for.

---

so my new idea for Capitalized and UPPERCASE is as follows. The previous idea was that UPPERCASE was meaningless identifiers, whereas Capitalized was something where metaprogramming was allowed to reflect on the capitalized string.

My new idea is that you can reflect on either of them, and the difference is that UPPERCASE is purely an annotation attached to the AST, whereas Capitalized is an ordinary node (identifier) within the AST, but one which metaprogramming can reflect upon and alter.

UPPERCASE is really just shorthand for ^UPPERCASE, which is itself just short for ^{UPPERCASE}. In the general case, eg when the annotation is a multiword expression, you have to use the long form, with ^{}

---

for languages in which '::' is EOL type annotation (and we might use it this way), :: is just a special case of the general case of annotations. That is, it's a node on the metalevel pointing to a node on the value level, such that the edge type (the type of the arrow which is pointing) is 'type annotation'.

Perhaps a :: x y is just short for a^{type-annotation: x y}.

note that the thing on the right of the :: is just an expression whose result is of type 'type'


since we have reified graphs here, we need general syntax for annotating edges of the AST, not just nodes.

one idea is ^{} for node annotation, and ^^{} for edge annotations. Eg:

^{annotation on the whole functionA definition}def ^{annotation on the functionA name}functionA^{annotation on the functionA definition argspec} (x, y) ^{annotation on the functionA definition block}{ ^^{annotation on the edge/connection between the functionA definition block, and the statement 'return x+y'} return x+y }

---

if type variables without the '$' prefix are just ordinary identifiers, then you can use them to abbreviate long types. You could say that type variable assignments in enclosing lexical scopes are available for use in type expressions.

eg:

x = [0] xtype = list int def functionA { y = [root:x] :: Tree xtype }

note that in the above example, rather than syntactically putting the 'xtype = list int' into some separate 'type annotation' segment, it's just right there along with the value computations.

this may or may not be a bad idea. Currently, i feel that a sufficiently smart compiler should be able to deduce which assignments are statically known types, and separate them out itself if it wants to.

note that type variables WITH the $ prefix are pattern metavariables, eg 'Tree $x' is a type (pattern) that matches any type of the form Tree(x), for any x.

---

still thinking we might want syntax for at least the enumeration special case of dependent types (namely, the type of an integer whose value is guaranteed to be below some ceiling). How about int<ceiling; eg int<5 is an integer which is always one of 0,1,2,3,4.

---

futhermore, in order to be able to have a type for non-empty lists (which is useful for maybe-like constructs), we need a way to declare the type of something which is only generated from one of the many constructors of some other type.

Eg if the constructors of a list are EmptyList?