One thing about PicoLisp that might stick out for people coming from CL,
Scheme, or Clojure is that it's dynamically scoped (like most Lisps,
historically), so you can't make closures. Compare this Scheme session:
#;1> (define (make-counter)
(let ((i 0))
(lambda () (set! i (+ i 1)) i))))
#;2> (define counter (make-counter))
#;3> (counter)
1
#;4> (counter)
2
#;5> (counter)
3
To this PicoLisp one: ? (de make-counter ()
(let (i 0)
'(() (setq i (+ i 1)) i)))
-> make-counter
? (setq counter (make-counter))
-> (NIL (setq i (+ i 1)) i)
? (counter)
-> NIL
? (setq i 10)
-> 10
? (counter)
-> 11
Using `curry` and patterns, you can do substitutions into a "lambda", which
can look like a closure, or not: ? (de make-adder (@base)
(curry (@base) (n) (+ @base n)))
-> make-adder
? (setq add-three (make-adder 3))
-> ((n) (+ 3 n))
? (add-three 5)
-> 8
? (de make-counter ()
(let (@i 0)
(curry (@i) () (setq @i (+ @i 1)) @i)))
-> make-counter
? (setq counter (make-counter))
-> (NIL (setq 0 (+ 0 1)) 0)
? (counter)
!? (setq 0 (+ 0 1))
0 -- Variable expected ; oops, we're trying to redefine 0