bakpakin/Fennel

Strict globals forbid correct code

anuvyklack opened this issue · 5 comments

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)))])

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.

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

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.

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.

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.