closer.js
closer.js copied to clipboard
parsing issues
Really nice project!
I noticed a few issues (based on my recent experience building a linter in my free time) with the parsing that you might be interested in:
Sometimes the tokens are not recognized properly. In this:
#(%abc) ; one token "%abc" -- should be error -- %, %&, %<number> are the legal forms
#(%200) ; one token "%200" -- should be error -- max number of params is 20
#(%20 abc%20) ; should be parsed as 2 tokens: "%20" and "abc%20"
Some valid trees are rejected:
(def y "abc" 123)
(quote (def))
Different meanings for symbols in different contexts:
(def %abc 123) ; %... can be used as a normal symbol outside of shorthand functions
(def def 3) ; `def` acts like a normal symbol when not in operator position
[def] ; => [3]
(def fn) ; legal
fn
, let
, loop
aren't special forms (the official Clojure docs are wrong about this):
user=> (special-symbol? 'fn)
false
user=> (special-symbol? 'def)
true
Of course, all these are assuming that exact compatibility with the main Clojure version is desired. If not, sorry for bothering you!
Hey @mattfenwick, thanks for providing the exhaustive details. I'm surprised fn
, let
and loop
aren't really special forms. I can't imagine how they could be implemented as macros or functions over other special forms -- do you have any relevant links on this?
Since closer.js was built for use on codecombat, exact compatibility with Clojure is not a top priority right now. There are other, pressing issues to tackle first -- like implementing macros (have any ideas?) and supporting more Clojure core functions / macros. But I imagine exact compatibility will be a concern in the future, so let's keep this issue open for now. Of course, there are also a few bugs outlined in your list that should not be kept for later.
Hi @vickychijwani -- thanks for taking the time to respond!
The faux "special forms" are defined in core.clj. So there are some related special forms -- fn*
, let*
, loop*
-- that are similar but don't support destructuring. (The main difference (that I'm aware of) between special forms and macros is symbol resolution).
Ah, that explains it. So they're macros that expand to the hidden special forms (fn*
, let*
and loop*
). Thanks for clearing that up!