Closed borkdude closed 5 months ago
I would not view this as a bug, but as intended semantics: do ->
literally means to build a function (->
) and call it (do
) — very different from the TC39 do
proposal. This functionality of do ->
is useful, for example, if you want to build a generator right now. For example:
processGenerator do ->
yield 1
yield 2
yield 3
Here's [a more real-world example with async](https://coffeescript.org/#try:await%20Promise.all(%0A%20%20for%20url%20of%20urls%0A%20%20%20%20do%20-%3E%20await%20(await%20fetch%20url).json()%0A)), where do
enables await
syntax without "infecting" the entire function:
Promise.all(
for url of urls
do -> await (await fetch url).json()
)
I think where CoffeeScript's behavior is less intuitive is when it happens with implicit IIFEs; see #5363 where I asked about return
inside a for
loop, but the same applies to yield
within a for
loop. We actually get my intended behavior from #5363 in Civet, but not when it's a for-loop expression which, as #5363 details, is hard to transpile. We've discussed this some in a Civet context, where we plan to do more thorough rewriting to handle cases like this, but haven't tackled it yet. See https://github.com/DanielXMoore/Civet/issues/202 and https://github.com/DanielXMoore/Civet/issues/381.
Makes sense, I interpreted do ->
as the TC39 proposal. The babel transpiler for that proposal does the thing I would expect (for implicit IIFEs).
Cool, I didn't know about that plugin. I agree that it works well with yield
, but it doesn't work well with return
(compare with the proposal) and doesn't support break
.
but it doesn't work well with return and doesn't support break
luckily for my language (squint) this isn't a problem since it is expression-oriented and therefore doesn't support explicitly returning things. I think it could be a reasonable trade-off for do expressions too since they have an implicit return value, maybe it should even barf on an explicit return
Here is an illustration of generator functions in squint
I expect yield to be used anywhere in a function, but it seems do -> breaks this expectation since it's compiled to an IIFE.
Repro:
https://coffeescript.org/#try:perfectSquares%20%3D%20-%3E%0A%20%20num%20%3D%200%0A%20%20do%20-%3E%0A%20%20%20%20y%20%3D%201%0A%20%20%20%20yield%20y%3B%0A%20%20loop%0A%20%20%20%20num%20%2B%3D%201%0A%20%20%20%20if%20num%20%3E%2010%20%0A%20%20%20%20%20%20break%0A%20%20%20%20yield%20num%20*%20num%0A%20%20return%0A%0AglobalThis.foo%20%3D%20perfectSquares()%0A%0A
Note that I'm only theoretically interested in a solution as I'm writing my own to-JS transpiler and was wondering if CoffeeScript authors have thought about this more than I have. More info here.