Hi, If I understand correctly what you said the reason for (let K 3 '(print `K)) returning (print NIL) rather than (print 3) [being K not previously defined] is that the sequence of steps is:
Almost, there is a slight confusion in step 2. I would revise it like so: 1- read the whole let expression , here (let K 3 '(print `K)) 2- reader encounters `K, thus K is evaluated (returns NIL) immediately, and that result is substituted into the original expression before any runtime evaluation takes place. So now the expression is (let K 3 '(print NIL)). 3- evaluate the "let prog" in the context stated by let bindings, thus evaluates '(print NIL) in a context where K is bound to 3, but obviously K is not used in the "let prog" if so, would be hard to make the jump over step 2? that is making the quote protecting the whole expression and evaluating the read-macro ` only in step 3 when the expression is evaluated under symbol bindings stablished by let? maybe I'm saying nosense, sorry in advance! ;-) This issue here is readtime vs runtime. The read-macros will not be able to access symbol bindings created at runtime. You will need to use 'fill' or 'macro' for this. : (let K 3 (fill '(print K) 'K)) -> (print 3) # or : (let @K 3 (macro '(print @K))) -> (print 3) This article discusses the subtleties of the process in more detail: http://picolisp.com/wiki/?readvsruntime Happy hacking, Erik