bakpakin / Fennel

Lua Lisp Language
https://fennel-lang.org
MIT License
2.42k stars 124 forks source link

Strict globals forbid correct code #441

Closed anuvyklack closed 1 year ago

anuvyklack commented 1 year ago

When I try to compile next code, I get an error: unknown identifier in strict mode: handle

(let [(handle pid) (uv.spawn cmd {} (fn [code signal]
                                      (handle:close)))]
  ...)

however when I compile it with --globals "*" flag I get correct code:

local handle, pid = nil, nil
local function _10_(code, signal)
  handle:close()
end
handle, pid = uv.spawn(cmd, {}, _10_)

An alternative way is to create the variables before, but that looks ugly.

(var (handle pid) (nil nil))
(set [(handle pid) (uv.spawn cmd {} (fn [code signal]
                                      (handle:close)))])
anuvyklack commented 1 year ago

Update: Also even with --globals "*" flag I get an error:

runtime error: attempt to index a nil value (global 'vim')

I am writing for Neovim which provide access to its internal stuff from Lua scripts by vim global table. So it appears that currently I can't compile my script at all.

anuvyklack commented 1 year ago

I am invoking fennel compiler from python script using this command:

fennel --raw-errors --globals "*" --add-macro-path MACRO_PATH --compile SRC > OUT

When I delete --add-macro-path MACRO_PATH flag, the strict global checking turns off at all, which allows me to compile scripts. But I need to type a full path to the macro file. And life over all become harder, when you spent some time seeking bug, and found that you've made a typo in a variable name

technomancy commented 1 year ago

This is actually the same underlying problem as #299; it has to do with the way that functions are emitted as locals every time rather than purely anonymously in the compiler output. It's a very difficult issue to fix since the compiler makes a lot of assumptions about chunks being statements.

It doesn't really have much to do with strict globals checking, other than that turning off all checks altogether just happens coincidentally to be a workaround for the underlying issue.

In the first reply you've pasted a runtime error, which isn't actually a problem in Fennel but in whatever runtime you're using.

In general, the pattern you've identified as a workaround with var is a normal way to implement mutual recursion. But you're also right that in this one particular case, if #299 were fixed, then this should technically be possible without it.

technomancy commented 1 year ago

I don't know if I understand what you're saying about --add-macro-path affecting the globals behavior; could you clarify about that? If you could provide an example which demonstrates the problem, it would be helpful.

technomancy commented 1 year ago

I'm going to close this because we're tracking the underlying issue already in #299 but it sounds like you might have another separate issue; if so feel free to open a new issue report with a description of the problem. Thanks.