-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Wrapping functions #118
Comments
I don't think there's a nice way. Main blocker really is a decent syntax ?! |
I wouldn't mind wrapping just the top layer. |
Thing is (=>) is already valid syntax, so I think your proposition would complicate the parsing quite a bit. |
I'm a little confused -- Tesco, why would you need to make a closure wrapper in CoffeeScript? Let's see a real example. Passing a function to another is one thing -- and that's what the block syntax is for, but this is a bit stranger... |
Without closure, name continues to change and the inner code will always call the last name that exists on |
It's by no means a ridiculous proposal -- but part of the idea of CoffeeScript is that you shouldn't have to closure-wrap yourself in most cases, because we're going it for you when required. So let's look at an alternative:
If you're using
It's a good bit longer that way, though. |
Doesn't that first example have precisely the same problem? |
Oy. It sure does have the same problem. Sorry about that. Your original wrapping proposal is the only way to make this work. One issue with defining a new syntax is that, once you need to add the wrapper, you might as well just use the equivalent |
|
I don't think it's trivial at all. Since the current syntax for this is clunky (albeit still streamlined when compared to JavaScript), I'd love to see what your ideal syntax for this purpose would look like. It seems like what you need is:
At first blush, it seems like we could easily use the block-indented scope to make a really nice construct for this. |
If the proposed fn2: (=>)(x,y) ... |
or perhaps just fn: =>() ... fn2: =>(x,y) ... So if you wanted to port jQuery (I know it does quite work...), you might do: window, undefined =>(window) ... |
In the specific case of capturing loop variables in an inner function, how about automatically providing a closure wrapper? e.g.
...
|
Fantastic, thanks sethaurus. No new syntax required, and no special thought. Now, on master, if you declare functions within the body of an array comprehension, an extra closure wrapper will be generated to prevent your variables from being shared with subsequent iterations. Here's the test case, which prints all
Closing the ticket... Let me know if it doesn't work for you, Tesco. |
I'm a little concerned about it automatically generating closures based on the loop's contents - for example, what if I wanted the variables to not be enclosed in the closure? How might I go about negating the effects of the automatic closure? What you're achieving is different to how Javascript works, and having it change invisibly seems dangerous to me. |
Totally dangerous, but we're already doing it (injecting closures) all over the place, in order to transform statements into expressions, which includes correcting inner references to "this" when we need to. In this case, the "this" of the function is going to become the object that it's attached to, because of JS's dynamic scope for "this", regardless of what its value is at definition time. The main issue here is sharing variables between iterations -- it should never be a problem for ordinary loops, because the variables are assigned and used immediately, and disappear at the end of the block. On the other hand, when you create a function within a loop, you probably expect the values of the variables created not to change out from right underneath your feet. For comparison, if you run the same pattern in Ruby, you get this:
Sure, it isn't one-to-one JS semantics, but seems more inline with expectations of lexical scope. If its too dangerous, we can absolutely revert it. But we should talk about a real-world use case where it doesn't do what you want. |
Oh, I see, you manually correct |
Quite right. This is much better than rewriting So, apart from |
Righto, I have no problem with this. |
Is there a nice way to wrap large functions? I have a habit of going overboard with closures and it would be good to be able to wrap them easily, rather than
(=>
multiple_lines_of_code_here
)()
or when supplied as an argument
intFnString(5, (=>
multiple_lines_of_code_here
), "5")
Obviously this isn't a problem with single line functions.
intFnString(5, (=> 5), "5")
The text was updated successfully, but these errors were encountered: