Comment by ~andreyorst on ~technomancy/fennel
From https://github.com/bakpakin/Fennel/pull/423:
(macro rel-path [module from-macro?] `(.. (or (: (or ... "") :match "(.+%.)[^.]+") (if (= ... ,(if from-macro? "init-macros" "init")) "" (.. ... "."))) ,module))
This macro should cover most common cases for relative require from regular modules and macro modules.
Ticket created by ~andreyorst on ~technomancy/fennel
Here's a visual example: https://asciinema.org/a/va75Trg0KyJDj9KRI37OcURfd
And here's the same as the REPL output:
Welcome to Fennel 1.0.1-dev on PUC Lua 5.4! Use ,help to see available commands. Try installing readline via luarocks for a better repl experience. >> (% 2 0) >> (do (% 2 0) 1) runtime error: attempt to perform 'n%0' stack traceback: [string "do local _ = (2 % 0) end..."]:1: in main chunk /home/alist/.local/bin/fennel:780: in function ? [C]: in function 'xpcall' /home/alist/.local/bin/fennel:788: in function ? /home/alist/.local/bin/fennel:5836: in function ? [C]: in ?
Bisecting showed that the first bad commit is
04cc99ffe933cd4db920531639e77e365840ddc6
Ticket created by ~andreyorst on ~technomancy/fennel
It's possible to set the docstring metadata of a function at compile time, by putting a string literal as the first expression after the arglist, however it's impossible to do the same with the arglist metadata.
For documentation automation purposes, and (editor) discoverability it'd be great if the arglist could be altered without loading fennel compiler at runtime and calling
fennel.metadata:set
. Here are some cases for it:
- Functions that have heavy use of destructuring.
A result of the .doc command doesn't have to contain all this information, cluttering the docstring, instead a clear names can be provided to arguments, like often done with&as
. E.g. a function definition like this:(fn foo [{: some : heavy :destrutcturing [going here] &as arg-name}] "foo is a foo" nil)
is displayed as:Instead if we could override the arglist, we could keep the destructuring in the definition, but for the arglist just say that it's just>> ,doc foo (foo {&as arg-name :destrutcturing [going here] :some some :heavy heavy}) foo is a fooarg-name
. Alternativel, such destructuring can be analyzed and&as
name would be picked by the compiler automatically, but this is not always the desired behavior, I believe.- all-variadic functions.
Functions that are defined with only the[...]
arglist and then match on it somehow, convey nothing of what they're accepting. Altering such arglist can make documentation more clear.- Library case.
My fennel-cljlib library implements thefn*
macro, which has different notion of arglist, and to actually display it in the ,doc command I have to make this macro to check if metadata is enabled and require fennel at runtime to callfennel.metadata:set
so the correct arglist representation could be set to the function. This also makes it problematic, since to set a metadata we have to have a function's name, and thus wrap everything in a let binding, preventing some conventional patters, like returning a function from a file.This can be done if the
fn
special could accept a table in-place of the docstring, which would have the same syntax for metadata keys as accepted byfennel.metadata:set
:(fn add [...] {:fnl/arglist ["a" "b" "& rest"] :fnl/docstring "adds arbitrary amount of numbers"} (match (select :# ...) 0 0 1 ...))As with docstring, if nothing follows the table, it gets returned, so it shouldn't be a problem.
Ticket created by ~andreyorst on ~technomancy/fennel
trying to access unknown global crashes the REPL:
Welcome to Fennel 1.0.1-dev on PUC Lua 5.4! Use ,help to see available commands. Try installing readline via luarocks for a better repl experience. >> ,doc fennel fennel not found >> ,doc fennel.metadata lua: [string "return fennel.metadata"]:1: attempt to index a nil value (global 'fennel') stack traceback: [string "return fennel.metadata"]:1: in main chunk (...tail calls...) /home/alist/.local/bin/fennel:614: in function </home/alist/.local/bin/fennel:612> (...tail calls...) /home/alist/.local/bin/fennel:639: in function </home/alist/.local/bin/fennel:633> (...tail calls...) /home/alist/.local/bin/fennel:5710: in function </home/alist/.local/bin/fennel:5697> (...tail calls...) [C]: in ?
Trying to get documentation for a method call also crashes the REPL:
Welcome to Fennel 1.0.1-dev on PUC Lua 5.4! Use ,help to see available commands. Try installing readline via luarocks for a better repl experience. >> (local fennel (require :fennel)) nil >> ,doc fennel.metadata.get (fennel.metadata.get #<unknown-arguments>) #<undocumented> >> ,doc fennel.metadata:get lua: Compile error in unknown:1 multisym method calls may only be in call position * Try using a period instead of a colon to reference a table's fields. * Try putting parens around this. stack traceback: [C]: in function 'error' /home/alist/.local/bin/fennel:3406: in function 'fennel.friend.assert-compile' /home/alist/.local/bin/fennel:2250: in function 'fennel.compiler.assert' /home/alist/.local/bin/fennel:2797: in function </home/alist/.local/bin/fennel:2795> (...tail calls...) /home/alist/.local/bin/fennel:3111: in function 'fennel.compiler.compile-stream' (...tail calls...) /home/alist/.local/bin/fennel:558: in upvalue 'resolve' /home/alist/.local/bin/fennel:614: in function </home/alist/.local/bin/fennel:612> (...tail calls...) /home/alist/.local/bin/fennel:639: in function </home/alist/.local/bin/fennel:633> (...tail calls...) /home/alist/.local/bin/fennel:5710: in function </home/alist/.local/bin/fennel:5697> (...tail calls...) [C]: in ?
Ticket created by ~andreyorst on ~technomancy/fennel
Submitting the bug from IRC channel so it won't be left out.
(or true (tset _G :foo :bar)) (and false (set _G.foo :bar))The code above compiles to the following lua:
_G["foo"] = "bar" do local _ = (true or nil) end _G.foo = "bar" return (false and nil)Wrapping
set
andtset
in ado
block fixes the compilation:(or true (do (tset _G :foo :bar))) (and false (do (set _G.foo :bar)))Side effects are correctly deferred:
local function _1_(...) _G["foo"] = "bar" return nil end do local _ = (true or _1_(...)) end local function _2_(...) _G.foo = "bar" return nil end return (false and _2_(...))This raises a question if
or
andand
should be implemented with macros that expand toif
as done in Clojure and Common Lisp:(macro or* [x ...] (if (= (select :# ...) 0) x `(let [or# ,x] (if or# or# (or* ,...))))) (macro and* [...] (let [nargs (select :# ...)] (if (= nargs 0) true (= nargs 1) ... (let [(first) ...] `(let [and# ,first] (if and# (and* ,(select 2 ...)) and#)))))) (or* true (tset _G :foo :bar)) (and* false (set _G.foo :bar))No IIFE needed in this case:
do local or_2_auto = true if or_2_auto then else _G["foo"] = "bar" end end local and_2_auto = false if and_2_auto then _G.foo = "bar" return nil else return and_2_auto endThe
if
itself may be transformed to IIFE to perform correctreturn
in case of multiple values, but this should be well tested.
Comment by ~andreyorst on ~technomancy/fennel
However, the first one should not work at all; it looks like somehow strict globals checking stopped working in the repl.
I agree. This was fixed in a11d3658
REPORTED
RESOLVED FIXEDTicket created by ~andreyorst on ~technomancy/fennel
I'm not sure how exactly this should work but the current behavior is probably inaccurate:
Welcome to Fennel 1.0.0-dev on Lua 5.4! Use ,help to see available commands. Try installing readline via luarocks for a better repl experience. >> (tset _G :foo (fn [] (print :foo))) nil >> (foo) foo >> (tset _G :foo-bar (fn [] (print :foo-bar))) nil >> (foo-bar) runtime error: global '__fnl_global__foo_2dbar' is not callable (a nil value) stack traceback: ...
Comment by ~andreyorst on ~technomancy/fennel
That's even better
Comment by ~andreyorst on ~technomancy/fennel
thanks! Really glad that we have it before 1.0.0. as I'm planning on making 1.0.0 mandatory for most of the libs when in will be out.
Comment by ~andreyorst on ~technomancy/fennel
the
opts.nval
value is equal to1
in cases like(and (do 42) false)
, and the branching is done depending ifnval
is set https://git.sr.ht/~technomancy/fennel/tree/main/item/src/fennel/specials.fnl#L121-131