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

Emit anonymous functions as literals without binding them to locals #384

Open
6cdh opened this issue Aug 16, 2021 · 3 comments
Open

Emit anonymous functions as literals without binding them to locals #384

6cdh opened this issue Aug 16, 2021 · 3 comments

Comments

@6cdh
Copy link

6cdh commented Aug 16, 2021

Description

Too many local variables if there are too many functions in a table.

Reproduce

Compile this code

[#1, #1, ..., #1] ; 200+ times

Result

local function _1_()
  return 1
end
local function _2_()
  return 1
end
...
return {_1_, _2_, ...}

Run this code then get main function has more than 200 local variables.

Expect

return {
  function()
    return 1
  end,
  ...
}

Or anything else that can get rid of this error.

Details

Lua restricts the number of local variables to 200. We can inline elements of tables like the original Fennel code do rather than blindly generate local variables then reference them.

Info

  • Fennel version: Fennel 0.10.1-dev commit id #50dfc7f
  • Lua version: LuaJIT 2.1.0-beta3
@technomancy
Copy link
Collaborator

This is probably the longest-standing annoyance in the entire Fennel compiler.

I've tried to fix it multiple times but it's a lot more subtle than it looks. But I would like to get the compiler emitting functions as bare literals at some point.

@technomancy technomancy changed the title Too many local variables error when 200+ functions in a table Functions are always emitted as locals Aug 16, 2021
@technomancy technomancy changed the title Functions are always emitted as locals Emit anonymous functions as literals without binding them to locals Aug 16, 2021
@6cdh
Copy link
Author

6cdh commented Aug 17, 2021

Thanks. As a workaround, I divided a fennel source file into multiple small files.

@technomancy
Copy link
Collaborator

To clarify, the difficulty is that the compiler has a fairly deep-seated assumption that all expressions are just single strings and that larger chunks of code consist solely of statements. (This is derived from Lua's own semantics.) That's why a function first gets compiled to a local binding statement, and then its local name is used when you need to refer to the function as an expression.

Reversing this for functions in general would be difficult; the code which handles indentation of output currently operates on chunks of statements and is quite a bit downstream from anything that knows about expressions. However, it might be possible to convert hashfns specifically to expressions without statements, since they tend to be shorter and are frequently one-liners, lacking support for indentation might not be so bad.

(But for a workaround to the problem you ran into, you don't need multiple files, you just need multiple scopes. Move half your function values out of the top-level and into a nested scope and the error will go away. Or recompile Lua to boost the 200 limit, haha)

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

2 participants