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

Support actual closures via struct #267

Open
mbekkomo opened this issue Jul 5, 2024 · 0 comments
Open

Support actual closures via struct #267

mbekkomo opened this issue Jul 5, 2024 · 0 comments

Comments

@mbekkomo
Copy link

mbekkomo commented Jul 5, 2024

WARNING: Please, read this note carefully before submitting a feature request:

It is important to realize that this is NOT A SUPPORT FORUM, this is for ISSUES ONLY.

If you need support, have questions, ideas to discuss you should use
the Nelua Discussions forum or
the Nelua Discord server.

Please, before submitting a new issue, verify the following:

  • You have tested it on latest Nelua version from master branch.
  • You have checked that there is no similar feature already implemented or requested.

Feature motivation

It's known that Nelua does not support closures. Once you had a closure in your code, Nelua will complain about that it can't handle closures.

test.nelua:10:5: from: AST node Block
    return x
    ^~~~~~~~
test.nelua:10:12: error: attempt to access upvalue 'x', but closures are not supported
    return x

Feature description

But with records, we can somewhat implement a type of closure in Nelua.

local function add(x: integer)
  local closure = @record{
    -- Generated field
    x: integer
  }
  
  function closure.closure(y: integer)
    return self.x + y
  end
  
  return (@closure)({x})
end

So if you have a function with closure like this.

local function idiv(x: integer)
  return function(y: integer)
    return x // y
  end
end

Nelua should generate the following code as this.

local function idiv(x: integer)
  local closure = @record{x: integer}
  
  function closure:closure(y: integer)
    return self.x // y
  end
  
  return (@closure)({x})
end

And then will use closure.closure as closure when it's returned from function.

Code example

Provide minimal code example for the feature.
Please, format the code properly and try to keep it as simple as possible, just focusing on the feature.

local function add(x: integer)
  return function(y: integer)
    return x + y
  end
end

print(add(1)(2))

Will generate a code (in C but this is explained in Nelua).

local function add(x: integer)
  local closure = @record{
    x: #[x.type]#
  }
  
  function closure:closure(y: integer)
    return self.x + y
  end
  
  return (@closure)({x})
end

print(add(1):closure(2))

Describe alternatives you've considered

A clear and concise description of any alternative solutions you've considered.

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

1 participant