IVY_KW_VAR is not treated as an expression start token (as variable declarations are not
strictly expressions). so the lambda parser did not create a block parser context
when it encountered this keyword.
additionally, unnamed complex-msg args no longer need to be prefixed
with a colon. this allows complex-msgs to more closely emulate
traditional function calls. this also applies to the call-operator.
for example, take the following lambda:
var f = [ :x :y | ^x * 2 + y ].
before, this lambda would be invoked using the following syntax:
f(:2 :4).
now, this syntax is used instead:
f(2, 4).
previously, an expression like:
x arg1:a arg2:(c subArg:d).
were being parsed incorrectly. This expression was parsed
as single -arg1:arg2:subArg: message being sent to x. the
parentheses around the `c subArg:d` sub-expression were
being ignored.
now, this expression is correcly parsed as the value
of `c subArg:d` being passed as a parameter to the message
-arg1:arg2:
the var keyword allows greater control over what scope a
particular variable exists in. it clarifies whether a new
variable is being defined or an existing variable is being
assigned to. it will also facilitate the implementation of
global variables.
the caller can now provide a pointer arg to ivy_ast_node_iterate, which will
be forwarded to the specified callback function each time it is called.
the iterator now behaves similarly to fts, in that it visits each node
in both pre-order and post-order, and indicates to the callback whether
the current iteration is pre- or post-order.
the () operator can be used to call lambdas in a more functional way than the standard
message-send syntax
for example, with a lambda stored in variable `x`:
x(a:2 b:6).
is equivalent to
x call(a:2 b:6).