[Nickle]Array comprehension syntax
Bart Massey
nickle@nickle.org
Sun, 04 Aug 2002 23:34:03 -0700
My principal syntactic objection are that both the formal
and result types of the comprehension func, together with
the fact that it's a func and its arity, are already known.
Thus, the explicit func() is inappropriate: the
comprehension should just take formal names and an
expression, like the Smalltalk block construct.
Perhaps something like
int[10,10] a = { =(i,j) i * j ... };
is not too bad? Note that this syntax might also allow
things like
int[10] a = { =(i) i + 1, =(i) i + 2, =(j) j * j ... };
although I can't for the life of me figure out how this
would be useful :-).
Note also that if you want a lambda for structure it's not a
big deal to have one:
int[11] a = { =(i)
int func(int j) {
if (j < 5)
return j;
return 10 - j;
} (i) ... };
although arguably better here is
int[11] a = { =(i) ({ if (i < 5) return i; return 10 - i; }) ... };
and arguably better still is
int triangle(int n, int i) {
int b = n // 2;
if (i < b)
return i;
return 2 * b - i;
}
int[11] a = { =(i) triangle(11, i) ... };
although in all these examples it is troubling that changing
the size of a will not automatically work, so maybe
int[11] a = { =(i) triangle(dim(a), i) ... };
works, although I don't think a is scoped in yet in the
initializer :-) so probably not. Sigh.
The other classic approach is to not let the user name the
formals, but instead pre-supply names: something like
int[11] a = { = triangle($#, $1) ... };
or perhaps something less ugly.
Bart
In message <E17bBub-00017c-00@localhost> you wrote:
>
> Array comprehensions are lambdas evaluated to initialize an array; they're
> passed the index of the desired element and compute that element.
> Essentially, they're a shorthand notation for:
>
> int[*,*] a = [2, 2];
>
> for (int i = 0; i < 2; i++)
> for (int j = 0; j < 2; j++)
> a[i,j] = lambda (i,j);
>
> I've got the underlying code all built for compiling and executing these,
> but I'm a bit stuck on the syntax. My current (lame) syntax looks like:
>
> int[*,*] a = [2, 2] { = int func (int i, int j) { return i*j; } };
>
> Actually, any expression which evaluates to a function can be used inside
> the initializer:
>
> int c (int i, int j) { return i * j; }
>
> int[*,*] a = [2, 2] { = c };
>
> I'm really not excited about this syntax and am looking for suggestions.
> However, even with this weak syntax, compose looks a lot nicer:
>
> poly (poly...) compose (poly f, poly g) {
> return poly func (poly args...) {
> poly(int) pick(int start) {
> return func (int i) { return args[start+i]; };
> }
> return f (g ((poly[func_args(g)]) { = pick(0) } ...),
> (poly[func_args(f)-1]) { = pick(func_args(g)) }...);
> };
> }
>
> The only problem is that the arguments 'f' and 'g' aren't statically
> typechecked to accept only functions. We don't have any syntax for
> a function which takes an arbitrary number of arguments, all we have
> is syntax for a function which takes a variable number of arguments;
> the problem is that:
>
> poly(poly...) a = poly func (poly g) { return g; }
>
> is currently a type error (Incompatible types 'poly(poly ...)', 'poly(g)')
>
> We need a formal spec for our current type system...
>
> -keith
>
>
>
> _______________________________________________
> Nickle mailing list
> Nickle@nickle.org
> http://nickle.org/mailman/listinfo/nickle