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

Implement Closure #2753

Open
1 of 7 tasks
HerrCai0907 opened this issue Sep 29, 2023 · 3 comments
Open
1 of 7 tasks

Implement Closure #2753

HerrCai0907 opened this issue Sep 29, 2023 · 3 comments

Comments

@HerrCai0907
Copy link
Member

HerrCai0907 commented Sep 29, 2023

Feature suggestion

#798 and #1240 has discussed lots of thing about closure, but maybe there are some outdated information.
So I want to start to discuss it in some new page.

Project State

  1. function object will be compiled as static object in data area.
  2. function object store function index in table and null env.

High Level Requirement For Closure

  1. Every function object from the same FunctionExpression will have different env.
  2. When call function object, function can use (read / write) the variable in env and upper function env.
  3. (Optional) If function is not a closure function, supporting closure has no or small influence this function in the perspective of code size and spend.

What should we do to support closure

For better code review, I think maybe we can support it step by step. I will post everything we need to implement closure. Please correct my mistakes and omissions.

let upper_function = () => {
  let variable_in_upper_function: i32 = 0;
  let current_function = () => {
    let variable_in_current_function: i32 = 0; // used in lower function.
    variable_in_upper_function = 1; // variable declared in upper function.
    let lower_function = () => {
      variable_in_current_function = 2;
    }
  }
)

code gen

semantic

  • we need a way in compiler to create / modify class definition.
  • analyze which function expression should enable closure supporting.
  • analyze which local variable is used in lower function.
  • analyze which identifier is declared in upper function. (already support in resolver.ts)
@alienself
Copy link

Any progress on this @HerrCai0907 ?

I personally truly wish we had threads and closure support, I am looking at the AssemblyScript since a few years now, waiting for those features to land to be able to use it more often and I feel like I am not alone.

This project is super exciting and yet we are missing core features for the language to be more broadly used.

@sasq64
Copy link
Contributor

sasq64 commented Oct 17, 2024

Has there been talk of not implementing full closures, but enough "syntactic sugar" to make lambdas useful?

Basically look at old java or c++ and do something like;

  • Define an "internal" interface Function { call(...any[]): any; }
  • Make lambdas convert to an object implementing this interface as needed
  • Create fields for every variable in the outer scope that is accessed by the lambda, and assigned them by value

So something like (pseudo-code warning);

class Array {
  map(function: Function): Array {
   // ...
   function.call(...)
  }
}  
  
let a: u32 = 1
let b = new MyObj()

let newList = someList.map(item -> item + a + b.get())

Where the compiler transforms the last line to;

class UnNameableFunction implements Function {
   a: u32
   b: myObj
   call(item: u32): u32) {
     return item + a + b.get()
   }
}

temp = new UnNameableFunction()
temp.a = a
temp.b = b
let newList = someList.map(temp)   

@HerrCai0907
Copy link
Member Author

It need more work than I expected. Closure is a big challenge since it need lots of compiler internal feature to support. e.g. create a temporary object / class definition in local context as the definition of closure object.

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

No branches or pull requests

4 participants