Olical / aniseed

Neovim configuration and plugins in Fennel (Lisp compiled to Lua)
https://discord.gg/wXAMr8F
The Unlicense
610 stars 28 forks source link

Lambda function defined with defn? #121

Open katawful opened 2 years ago

katawful commented 2 years ago

In Clojure, a function defined with defn can take multiple argument lists to achieve multi-arity. In Fennel, this achieved with simply passing nil to unneeded args. If an arg is strictly needed, lambda is used over fn:

(defn func 
  ([arg1] (print arg1))
  ([arg1 arg2 arg3] (print arg1 arg2 arg3)))
(func 1) ; --> prints '1'
(func 1 2 3) ; --> prints '1 2 3'
(fn func [arg1 arg2 arg3] (print arg1 arg2 arg3))
(func 1) ; --> prints '1 nil nil'
(lambda func [arg1 arg2 arg3?] (print arg1 arg2 arg3?))
(func 1) ; --> Missing argument arg3? on unknown:4

Different ways to achieve the same end goal, mostly because Fennel is based on Lua which has its own limitations compared to Java

In Aniseed however, defn only compiles to the named function desired defined with fn, which is then added to the current module. Example:

(defn func [arg1 arg2 arg3?] (print arg1 arg2 arg3?))
(func 1) ; --> falsely prints '1 nil nil' instead of a runtime error
; expansion
["ANISEED_DELETE_ME"
 (fn func [arg1 arg2 arg3?] (print arg1 arg2 arg3?))
 (tset *module* "test" test)]

arg3? cannot be nil checked and return a runtime error as defn always compiles to fn. This seems incongruent with what this macro is attempting to mimic

Olical commented 2 years ago

Hmm, this would be a breaking change for all users I think, anyone who allowed nils or optional args would suddenly have this code break on update.

If I ignored backwards compatibility I guess defn would need to wrap your functions you provide to switch to the one with the correct arity AND use lambda instead for arity checking. Maybe this could be some sort of option you can switch off / have to opt into.

Maybe instead I could define defns/defn!/defun/deflambda that has this new, more locked down, but multi arity supporting idea.

katawful commented 2 years ago

If it would lead to breakages then a new macro would be far more ideal yeah. deflambda seems like the most reasonable name to me, as defn already contains fn from fennel's keywords