Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

let for #164

Closed
vendethiel opened this issue Sep 5, 2012 · 23 comments
Closed

let for #164

vendethiel opened this issue Sep 5, 2012 · 23 comments

Comments

@vendethiel
Copy link
Contributor

jashkenas/coffeescript#2518

let for looks right to me, or for let

@satyr
Copy link
Owner

satyr commented Sep 5, 2012

for let maybe.

@vendethiel
Copy link
Contributor Author

Yes, for let sounds more correct syntax-wise - let for sounds more "english like" - but I know you believe english, or any natural language, is total crap. But I feel like it "adds" to the for syntax, without need.

@vendethiel
Copy link
Contributor Author

Any +1/-1 ? I think it's a regular use case (please let for).

@satyr
Copy link
Owner

satyr commented Nov 19, 2012

FWIW, ES6 version will look like: for (let x of xs)

@vendethiel
Copy link
Contributor Author

I doesn't matter much, both syntaxes are ok. True with the parenthesis it looks as nice, without a bit less - but I'd still be as happy.

@satyr
Copy link
Owner

satyr commented Dec 12, 2012

More analysis

We already got idioms using let and for together:

  1. let+for: Localizing the loop variables

    let
      for x, i of xs
        ...
    
  2. for+let: Creating fresh bindings for each iteration

     for x, i of xs
      let
        ...
    
  • The proposal may need to do both 1 and 2 efficiently to be worth a new construction.
  • let for as proposed is clearly confusing due to 1.
    • for let it is.
      • for let own or for own let, or both?

@vendethiel
Copy link
Contributor Author

This does not work :

for [x,y,z] of b
  let
    x + y + z

For let would capture any loop variable, even the destructurations
let own/own let it depends if the own is seen as a for construct or applicated to the variable, I suppose.

@satyr
Copy link
Owner

satyr commented Dec 12, 2012

This does not work

Nope, because auto-binding all of them is costly and may not be desirable (and you can always do for b => let [x, y, z] = & => ...).

depends if the own is seen as a for construct or applicated to the variable, I suppose

Both, I suppose.

@vendethiel
Copy link
Contributor Author

That's what the suggestion is for. Capture them. Maybe you can consider searching them in the block, like that/if. May be costly too, but not at runtime.

@satyr
Copy link
Owner

satyr commented Dec 12, 2012

Capture them

Naturally it will, since it won't have to expose the bindings to the outer scope as well.

for let bindings, i of xs => ...

will compile roughly as:

for tmp, tmp-i of xs
  let bindings = tmp, i = tmp-i
    ...

@vendethiel
Copy link
Contributor Author

Which is what we're looking for, isn't it ?

@vendethiel vendethiel mentioned this issue Feb 8, 2013
@vendethiel
Copy link
Contributor Author

Okay, I have something.
It's super ugly, super unoptimized etc etc. I wanted to use Call.let but I didn't managed to make it work :(.
d3223ce, cleaned up (a tiny bit) (allowing let for a, b of c then) by 44a0c90
Should work with makeReturn.

It got over my head really fast, I guess I need far more experience haha

@vendethiel
Copy link
Contributor Author

My diff is here. (still a @idx = left)
That's still pretty bad as I have basically no idea how coco works, but at least I don't feel so much shame when reading it.
It currently messes up the indentation, tho.

$ node lib/command -bce "let for a in b then"
var a;
for (a in b) {
(fn$.call(this, a))
}
function fn$(a){}
  • Not indented
  • Misses the ;
    is it because of LEVEL_TOP?

@satyr
Copy link
Owner

satyr commented Feb 18, 2013

  • Make it for let as decided above.
  • You need to build the let structure beforehand for non-cross-scope traversings (the normal mode of traverseChildren) from parent nodes.
  • Not indented
  • Misses the ; is it because of LEVEL_TOP?

@body is expected to be a Block.

@vendethiel
Copy link
Contributor Author

  • Make it for let as decided above.

Cleanest way I think of, to avoid messing with LoopHeads, would be to invert tokens in the lexer. Or is there anything else ?

  • You need to build the let structure beforehand for non-cross-scope traversings (the normal mode of traverseChildren) from parent nodes.

When is that ? In makeLet ((@let = true) -> this would be better) ?
I don't see how I can do that, I don't have access to svar/idx.
Or before calling While.compileBody ?
And isn't that going to break makeReturn ?

@Body is expected to be a Block.

Will fix.

Thanks

@satyr
Copy link
Owner

satyr commented Feb 18, 2013

would be to invert tokens in the lexer

Yep, you'd need to hack lexer.

Just using @index then ?

@index and @item would be in the let parameters beforehand.

Isn't that going to break makeReturn?

In this case you need to break it. It should return the whole let, not the last expression of let body.

@vendethiel
Copy link
Contributor Author

@index and @item would be in the let parameters beforehand.

Ok, so just before calling compileBody, else there's no access to @item.

In this case you need to break it. It should return the whole let, not the last expression of let body.

Right. So I need to makeReturn the @body I'm passing to let too.

I see a bit better how that goes. Will hack on it after lunch :).Thanks again.

@vendethiel
Copy link
Contributor Author

Ok, I think this is more correct : 7915ca5...1701fae
(with tests)

  • let for is not disallowed,currently. Should it be?

for let own or for own let, or both?

just inverting for/let currently, as I said

@vendethiel
Copy link
Contributor Author

@satyr are you okay with that ? Do you want me to add/change something, rule-wise or syntax-wise ?
Can you squash or do I need to reset hard + paste the files ? (I can't squash because windows)

@satyr
Copy link
Owner

satyr commented Feb 23, 2013

let for is not disallowed,currently. Should it be?

Yes. Should support for own let too.

are you okay with that ?

Doesn't work quite right in nested cases. Try e.g.:

*while a
  for let k in o
    return k

Similarly, any break/continue directly under for let should be an early error.

@vendethiel
Copy link
Contributor Author

2da664b

Should support for own let too.

Done. Disallowed let for


Similarly, any break/continue directly under for let should be an early error.

Not sure how to with continue. because of (or thanks to) While::addBody

for let a in b
  continue

will get optimized away and @getJump! will return nothing.
However this throws :

for let a in b
  1
  continue

No idea how to properly exclude return from @getJump! because it has no verb.
Here's my (dirty!) code :

      if @body.getJump!
        that instanceof Return or that.carp 'inconvertible statement'

For

eq '1', ''+for let a in [0]
  return 1

I get an error because of (or thanks to, again) Node::compileClosure. I don't mind adding a and not @let but it seems very dirty, again. Another flag, like @allowJumps ? (added in makeLet, ie). If I fix that everything should work (more or less?)


*while a
  for let k in o
    return k

Fails due to my previous point

@satyr
Copy link
Owner

satyr commented Feb 25, 2013

I guess I give up tutoring this time. Will get my hands dirty.

@satyr satyr closed this as completed in 81e9937 Feb 25, 2013
@vendethiel
Copy link
Contributor Author

Thanks for both!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants