Questions about Execution Order

2019-07-14 05:53发布

问题:

I'm trying to learn Common Lisp, and found something unexpected (to me) when trying something out in the repl. Based on order of execution in most programming languages, and the great first class function support I'd always heard about from lisp, I'd think the following should work:

((if t 'format) t "test")

In Ruby I can do:

if true
  Object.method(:puts)
end.call("test")

My thinking in how the above lisp code should work is that it should evaluate the inner lisp form, return format, then begin evaluating the outer lisp form, with format then being the first atom. I'd read that the first form needs to be a symbol, so I also tried ((if t format) t "test") even though my initial thought was that this would try to evaluate format before returning from the inner form.

I've noticed that sometimes lisp forms need to be preceded by #' in order for their results to be callable, but using (#'(if t 'format) t "test") doesn't work either. I'm sure I'm just misunderstanding something basic as I'm pretty new to lisp, but what's going on here?

回答1:

Common Lisp doesn't evaluate the first element of an expression normally. It has to be either a literal symbol naming a function, or a lambda expression.

If you want to call a function determined dynamically, you need to use the FUNCALL function:

(funcall (if t 'format) t "test")

This is analogous to the need to use the .call() method in Ruby.

What you tried would work in some other Lisp dialects, such as Scheme.