Evaluating vs Non-evaluating FunctionsThis concept is central to PicoLisp.
An evaluating function is generally more powerful, while a non-evaluating one might be more convenient. You can always use the evaluating version instead of the non-evaluating one (at the expense of more writing), but not vice versa.
'set' vs 'setq'The most obvious case is 'set' vs. 'setq'. A call to the (non-evaluating) 'setq'
(setq A 123)can be replaced with the (evaluating) 'set'
(set 'A 123)However, a call like
(set (foo (bar)) 123)cannot be replaced with 'setq', because the result of calling 'foo' must be found out by evaluation first
'let' vs 'bind'Again, it is a matter of convenience:
(let A (lines "lib.l") (* A A) )If you wanted to use 'bind' for that, you could do
(bind 'A (setq A (lines "lib.l")) (* A A) )or
(bind (list (cons 'A (lines "lib.l"))) (* A A) )'bind' is more flexible, as the symbols can be determined at runtime, while 'let' allows for a more readble code.
Note that in the Function Reference, evaluated arguments are marked with a quote. For example,
: (doc 'let) (let sym 'any . prg) -> any (let (sym 'any ..) . prg) -> anyand
: (doc 'bind) (bind 'sym|lst . prg) -> anyWe see that 'let' doesn't evaluate 'sym', while 'bind' does.
'run' vs 'prog'The same with the question of using 'run' or 'prog'.
'run' is a function which evaluates its argument, and then runs it
: (run (list '(println 1) '(println 2))) 1 2 -> 2After evaluation, 'run' sees the list ((println 1) (println 2)), and executes it.
So instead of 'prog', you could always use 'run' with a quoted argument list (analog to the 'set' / 'setq' example above):
: (prog (println 1) (println 2)) 1 2 -> 2 : (run '((println 1) (println 2))) 1 2 -> 2That's the whole difference.