musictheory / NilScript

Objective-C-style language superset of JavaScript with a tiny, simple runtime
Other
50 stars 5 forks source link

Rethink @each syntax #93

Closed iccir closed 8 years ago

iccir commented 8 years ago

Currently, @each uses the following syntax:

@each (var action in actions) {  [action doFoo];  }

to mimic the Obj-C for-in syntax:

for (FooAction *action in actions) {  [action doFoo];  }

The infrequently-used "use an existing variable" syntax is also supported:

oj:

var action;
@each (action in actions) {  [action doFoo];  }

Obj-C:

FooAction *action;
for (action in actions) {  [action doFoo];  }

The var action in the first example is a blatant lie. It doesn't actually make an action variable (oj uses a private internal variable), nor is action accessible elsewhere in the function scope. var action behaves more like let action:

@each (var action in actions) {  [action doFoo];  }
console.log(action); // Error, action isn't actually a var!

For 2.x, I'd like to change this: The infrequently used "use an existing variable" case of @each goes away and the common case simply becomes:

@each (action in actions) { [action doFoo]; }

(Similar to how the variable of a catch statement doesn't have var).

Edit: crossed out incorrect paragraph. See comment below

iccir commented 8 years ago

This bug is incorrect. I must have been severely low on coffee when I wrote it :)

The first example:

@each (var action in actions) {
    [action doFoo];
}

compiles into:

for (var action, $oj_t_2 = (actions), $oj_t_0 = 0, $oj_t_1 = ($oj_t_2 ? $oj_t_2.length : 0); $oj_t_0 < $oj_t_1; $oj_t_0++) {
    action = $oj_t_2[$oj_t_0];
    $oj_oj.msgSend(action,{ $oj_f_doFoo: 1 });
}

Internal temporary variables are used to keep track of state for everything but action. Hence, the var action isn't a lie.

That said, moving forward, @each should also allow let:

@each (let action in actions) {
    [action doFoo];
}