bobbicodes / bobbi-lisp

Interactive Lisp environment for learning Clojure
https://bobbicodes.github.io/bobbi-lisp/
0 stars 0 forks source link

Bug in anonymous function shorthand syntax #24

Closed bobbicodes closed 11 months ago

bobbicodes commented 11 months ago

This feature is implemented but it's buggy. I believe it is normally a reader macro. Here, the # is read as a reader dispatch form which is handled by the interpreter depending on whether it is a function or a regex.

The way it works is by constructing an arglist from the set of symbols in the expression that begin with %:

let fun = [types._symbol('fn')]
var args = Array.from(new Set(ast.toString().match(/%\d?/g))).map(types._symbol)
let body = ast.slice(1)[0]
fun.push(args)
fun.push(body)
return types._function(EVAL, Env, body, env, args);

But something must not be working as expected.

bobbicodes commented 11 months ago

For example,

(map #(cell (+ x %1) (+ y %2))

becomes

(map (fn (%1 %2/1) (cell (+ x %1) (+ y %2)))

(reduce #(get % %2) m ks) -> (reduce (fn (% %2/1) (get % %2)) m ks) (reduce #(map + (map min (butlast %1) (rest %1)) %2) -> (reduce (fn (%1 %2/1) (map + (map min (butlast %1) (rest %1)) %2))

What's going on? How does %2 become %2/1?

This one is slightly different: (mapcat #(for [p (k (- i 1) %2)] (conj p %)) -> (fn (%2 %/1) (for [p (k (- i 1) %2)] (conj p %)))

bobbicodes commented 11 months ago

It's happening in the symbol conversion:

['%2', '%'] -> [Symbol {value: '%2'}, Symbol {value: '%/1'}]

But it only seems to do it when there are 2 args. But this works fine:

(map symbol ["%2" "%"])
=> [%2 %] 
bobbicodes commented 11 months ago

Ok, I figured it out. I was mapping incorrectly:

Array.from(new Set(ast.toString().match(/%\d?/g))).map(types._symbol)
// should be
Array.from(new Set(ast.toString().match(/%\d?/g))).map(x => types._symbol(x))

Fixed!