speech impediment wrote:I thought this is pretty interesting in the Hyperspec:Although the order of evaluation of the argument subforms themselves is strictly left-to-right, it is not specified whether the definition of the operator in a function form is looked up before the evaluation of the argument subforms, after the evaluation of the argument subforms, or between the evaluation of any two argument subforms if there is more than one such argument subform. For example, the following might return 23 or 24.
(defun foo (x) (+ x 3))
(defun bar () (setf (symbol-function 'foo) #'(lambda (x) (+ x 4))))
(foo (progn (bar) 20))
I tested this code in both Clozure CL and SBCL and I got 24. It seems that these two implementations look up the definition of the operator after evaluation of the argument subforms. This is why I got confused about this code from Touretzky's book about helping functions.
- Code: Select all
(defun count-up (n) (count-up-recursively 1 n)
(defun count-up-recursively (cnt n)
(cond ((> cnt n) nil)
(t (cons cnt (count-up-recursively (+ cnt 1) n)))
I just didn't understand how you can use the function count-up-recursively when it wasn't even defined yet.
CL is a dynamic language. You are allowed to define functions later and even to redefine them if you like (except, perhaps, for explicitly inlined functions and ANSI functions). The hyperspec part you quoted is a clear example of that.