john-liu / jaql

Automatically exported from code.google.com/p/jaql
0 stars 0 forks source link

Incorrect handling of variables in default values of function definitions #56

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
There are two problems that occur when the default value of a Jaql function
contains a variable.

1. Variables used in the default value but not in the function body are not
part of the expression tree. A consequence is that rewrites marks those
variables as unused and might remove their definition from the tree.

Example: z=1; fn(x=z) x;
This decompiles to "fn(x=z) (z = 1, x)", which is incorrect because it does
not capture z in the default value. The correct value would be along the
lines "fn(x=(z=1,z)) x".

2. Variables used in the default value are not captured correctly. This
means that at the time the function is evaluated, those variables might not
be present anymore. Variables should be captured at the time the function
*definition* is evaluated.

Example: ( x=1, fn(y=x) y );
This does not compile; Jaql complains that variable "x" is undefined
because it is removed from the expression by a rewrite.

Original issue reported on code.google.com by Rainer.G...@gmx.de on 25 Sep 2009 at 4:13

GoogleCodeExporter commented 9 years ago
The proposed solution consists of two parts:

1. Associate local bindings with each Jaql function. Currently, a Jaql function
consists of a set of parameters with optional default value expressions and a
function body. Adding local bindings means that the function also contains 
(constant)
values for the free variables in the default value expressions and the body, 
which
binds those variables. For example,

z=1; fn(x=z) x;

will create a function that has a local binding "z=1". The function obtained by
evaluating the above expression decompiles to

const((z=1, fn(x=z) x))

The definition of a function literal has been extended to all Jaql expressions 
that
produce a function and are compile-time computable. Thus, the expression above
constitutes a function literal.

2. Put default value expressions into the expression tree. This makes them 
visible
during the compilation/rewrite process. Thus

( x=1, fn(y=x) y );

behaves as expected; x is not marked unused anymore.

Original comment by Rainer.G...@gmx.de on 1 Oct 2009 at 10:28

GoogleCodeExporter commented 9 years ago
Fixed in r373

Original comment by Rainer.G...@gmx.de on 1 Oct 2009 at 10:33