You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Closure and ClosureContext will not generated when no one variable was captured and use usual anonym functions.
ClosureContext will not created when only this was captured. In this case ctx param use to pass this reference.
It's likely we will need to allocate enclosed local values in a table or on the heap. Each pointer to those values will need to be stored in a table pointing to the heap.
This idea is Naive because the variables can no longer be treated like local variables because it's possible to modify local values before the function finishes executing.
I'm saying a in that example needs to exist on the heap for both b and c to access it, and the closure class needs to contain a Box<i32> that points to the heap location.
No, we don't need pass plain types by boxed references. Also found pretty clear article. So ClosureContext (LexicalEnvironment) should be little bit modifier and also store reference to it's parent LexicalEnvironment.
I planned to write a game engine use AS and I have programmed for a month, but now I give up AS and choose Rust because lack of supports for closures. Just let you know, It's not reasonable to not support closures in any case.
@luffyfly as a Functional Programming enthusiast I totally agree that closures are super useful and handy. But are you sure closures in Rust are implemented for Wasm efficient enough for your game engine?
As a general observation, in the current state Wasm presents a poor target for Functional Programming: doesn't efficiently support heavy use of function pointers, closures and GC. Moreover AssemblyScript is not really a Functional Language. And if you're programming in OO style it's not hard to implement purpose-built closures out of objects (going as far as Strategy Pattern if really needed).
@gabriel-fallen I'm pretty sure about that, because When I call the fetch() function of the web host from Wasm, I have to use closures as callbacks to avoid blocking the main thread.
doesn't efficiently support heavy use of function pointers
Closures in Rust are rarely represented as function pointers and instead as anonymous structs that have a "call" method that is statically dispatched rather than dynamically in almost all cases. The method is almost always inlined too, to the point where almost always you can't even tell it ever was a closure to begin with. It's very strongly a zero cost abstraction there.
Though I'm also wondering why you say function pointers aren't well supported by Wasm. As far as I know they are just functions stored in the function table and then called via an call_indirect and an index into the table. I don't see a problem with that approach, other than having to know all the functions that are going to be called indirectly ahead of time, but that's not a problem for a compiled language.
GC though is definitely a problem with closures for languages that don't have an ownership system.
@luffyfly Again closures and aysnc is absolutely different things. Dsynchrony without calling "then" in returned Promise but through "await" does not use dispatch at all. You decide what you want.
What is the current state of the closure implementation? I've seen several PRs related to closures, but none of them have been merged. I'm curious about what is the biggest block of closure implementation.
I am interested in using AssemblyScript, but must admit I am reluctant to use until closures are implemented. Yes, obviously there are workarounds, but they are inconvenient and add to code bloat. All TypeScript developers whom I assume this project hopes to pilfer are accustomed to the convenience of closures and to some degree of functional programming.
Many languages that target WASM already support closures, so I am confused as to what it is about AssemblyScript specifically that prevents closures from being implemented. I would be surprised if some limitation in WASM were a real roadblock. I saw some mentions of concerns around performance and allocations, which are reasonable, but I wonder if this is one of those situations where a bit of runtime efficiency is sacrificed for developer convenience? And the implementation wouldn't necessarily be the perfect implementation out the gate, so long as it is functionally correct. It could be refined or replaced later when new WASM features are introduced, or if a better implementation is worked out.
Reacted by Michael, William Raiford, Matias O, Troy, 맛카치, Wolfgang Steiner, felixroos, Samrat Bhandari, Congcong Cai, Dan Kersten and 1 more
Reacted by butterunderflow, Luo Gang, Troy and 맛카치
Upvoting this. Array find functions, like findIndex are pretty much useless without closures, as you can't compare an object property with some passed variable.
Reacted by Michael, Dmitry, Christophe Deveaux, 맛카치, George Phillips, Laurence 'GreenReaper' Parry, Artem Simonenko, Rodrigo Faria, Joachim Wester, LeeHo and 1 more
Thanks so much for working on this, @BlobMaster41; I was literally telling someone at Wolfery how closures weren't possible in room scripts yet and dropped by to see you were working on it. Will be keen to see it in action, assuming it lands...
Activity
jtenner commentedon Aug 28, 2019
I think we need to override the meaning of call indirect.
jtenner commentedon Aug 28, 2019
How would this transform?
MaxGraey commentedon Aug 28, 2019
@jtenner
MaxGraey commentedon Aug 28, 2019
Instead
we could just store index for indirect function table
jtenner commentedon Aug 28, 2019
How does this work with function dispatch?
For instance, let's say I pass the Closure Context out to js as a pointer. How can I re-call it?
jtenner commentedon Aug 28, 2019
Is there a way to make a table and add entries to it?
MaxGraey commentedon Aug 28, 2019
@jtenner actually you need pass only
fn/fnIdx. After that just use same approach as for anonymus indirect function calls.EDIT No you need unpack
fnfrom returnedClosureContextobject. Just provide another util for loaderMaxGraey commentedon Aug 28, 2019
Next example:
should generate:
jtenner commentedon Aug 28, 2019
Well I'm thinking about aspect collecting function pointers. How will aspect need to work with the function pointers?
jtenner commentedon Aug 28, 2019
My guess is that passing around the closure context will cause problems with manually using call_indirect like aspect does.
Also, this closure method doesn't handle multiple references to the same local.
B and c will get different versions of a.
MaxGraey commentedon Aug 28, 2019
@jtenner
You could get table and get function by index / ref. For example you have wasm:
than you js part:
jtenner commentedon Aug 28, 2019
It's likely we will need to allocate enclosed local values in a table or on the heap. Each pointer to those values will need to be stored in a table pointing to the heap.
This idea is Naive because the variables can no longer be treated like local variables because it's possible to modify local values before the function finishes executing.
MaxGraey commentedon Aug 28, 2019
Why?
Will generate:
jtenner commentedon Aug 28, 2019
I'm saying
ain that example needs to exist on the heap for bothbandcto access it, and the closure class needs to contain aBox<i32>that points to the heap location.MaxGraey commentedon Aug 28, 2019
No, we don't need pass plain types by boxed references. Also found pretty clear article. So
ClosureContext(LexicalEnvironment) should be little bit modifier and also store reference to it'sparentLexicalEnvironment.71 remaining items
luffyfly commentedon Oct 27, 2022
I planned to write a game engine use AS and I have programmed for a month, but now I give up AS and choose Rust because lack of supports for closures. Just let you know, It's not reasonable to not support closures in any case.
gabriel-fallen commentedon Oct 27, 2022
@luffyfly as a Functional Programming enthusiast I totally agree that closures are super useful and handy. But are you sure closures in Rust are implemented for Wasm efficient enough for your game engine?
As a general observation, in the current state Wasm presents a poor target for Functional Programming: doesn't efficiently support heavy use of function pointers, closures and GC. Moreover AssemblyScript is not really a Functional Language. And if you're programming in OO style it's not hard to implement purpose-built closures out of objects (going as far as Strategy Pattern if really needed).
luffyfly commentedon Oct 27, 2022
@gabriel-fallen I'm pretty sure about that, because When I call the fetch() function of the web host from Wasm, I have to use closures as callbacks to avoid blocking the main thread.
MaxGraey commentedon Oct 27, 2022
Just to note. Closures and async (cooperative multitasking) are two independent things
CryZe commentedon Oct 27, 2022
Closures in Rust are rarely represented as function pointers and instead as anonymous structs that have a "call" method that is statically dispatched rather than dynamically in almost all cases. The method is almost always inlined too, to the point where almost always you can't even tell it ever was a closure to begin with. It's very strongly a zero cost abstraction there.
Though I'm also wondering why you say function pointers aren't well supported by Wasm. As far as I know they are just functions stored in the function table and then called via an
call_indirectand an index into the table. I don't see a problem with that approach, other than having to know all the functions that are going to be called indirectly ahead of time, but that's not a problem for a compiled language.GC though is definitely a problem with closures for languages that don't have an ownership system.
luffyfly commentedon Oct 27, 2022
@CryZe I have tried function pointers, and It worked but It is so weird and difficult to use.
luffyfly commentedon Oct 27, 2022
@MaxGraey If AS has aysnc implementations, I will not take closures.
MaxGraey commentedon Oct 27, 2022
@luffyfly Again closures and
aysncis absolutely different things. Dsynchrony without calling "then" in returned Promise but through "await" does not use dispatch at all. You decide what you want.luffyfly commentedon Oct 27, 2022
@MaxGraey See #376 (comment).
Actually, I want both.
butterunderflow commentedon Dec 14, 2022
What is the current state of the closure implementation? I've seen several PRs related to closures, but none of them have been merged. I'm curious about what is the biggest block of closure implementation.
pchasco commentedon Jan 25, 2023
I am interested in using AssemblyScript, but must admit I am reluctant to use until closures are implemented. Yes, obviously there are workarounds, but they are inconvenient and add to code bloat. All TypeScript developers whom I assume this project hopes to pilfer are accustomed to the convenience of closures and to some degree of functional programming.
Many languages that target WASM already support closures, so I am confused as to what it is about AssemblyScript specifically that prevents closures from being implemented. I would be surprised if some limitation in WASM were a real roadblock. I saw some mentions of concerns around performance and allocations, which are reasonable, but I wonder if this is one of those situations where a bit of runtime efficiency is sacrificed for developer convenience? And the implementation wouldn't necessarily be the perfect implementation out the gate, so long as it is functionally correct. It could be refined or replaced later when new WASM features are introduced, or if a better implementation is worked out.
alienself commentedon Mar 15, 2024
Any update on this? Another year without closures 😢
Will 2024 the year of closures and thread support in AssemblyScript?
LeXXik commentedon Aug 23, 2024
Upvoting this. Array find functions, like
findIndexare pretty much useless without closures, as you can't compare an object property with some passed variable.leeho0108 commentedon May 22, 2025
any news for closures? Or is there any plan or time we can expected?
GreenReaper commentedon Dec 12, 2025
Thanks so much for working on this, @BlobMaster41; I was literally telling someone at Wolfery how closures weren't possible in room scripts yet and dropped by to see you were working on it. Will be keen to see it in action, assuming it lands...