Apply Has Its Secrets Too.


; What (apply f L) really does? If you only want to know what it
; does, and not how I concluded that, jump to the end of the post.

; But, is there any doubt what apply really does? It applies
; functions or macros on list. Here it is:

(println (apply + (list 1 2 3 4 5)))

; Result will be 15. What else? Well, there is the reason. One of
; the characteristics of Lisp is that some values evaluate to
; themselves - because of that we can sometimes write simpler
; expressions. On the other side, because of that, we do not have
; to face with errors, so we can successefully use some concepts,
; without really understanding it. At least, it holds to me. So,
; I have to write some tests to understand what really happens,
; ie. if + and 1, 2 ... are evaluated - and if they are, how
; many times!. I'll start with following.

(println (apply '+ (list 1 2 3 4 5)))

15

; Ha - it works. Quoted + doesn't harm! That means that not actually
; '+ is applied, but evaluated '+. If I defined some function f

(set 'f (lambda()(- (last $args) (first $args))))

; I can use apply in both of these forms:

(println (apply 'f (list 1 2 3 4 5)))
(println (apply f (list 1 2 3 4 5)))

; Both of these work and give same result - 4. Interesting, isn't
; it? Now, I'll try to quote those 's in the list:

(println (apply '+ (list '1 '2 '3 '4 '5)))

; It works. So, one might think that evaluated '+ is applied on
; evaluated elements of the list. But it is premature conclusion
; since list as operation itself will remove those quotes. So, we
; can test this one:

(println (apply '+ (list ''1 ''2 ''3 ''4 ''5)))

; Result is - ERR: value expected in function + : ''1

; OK; it would be too much. But look at that error: it appears
; that + got ''1 as argument! Not just '+, but ''+ - like one quote
; is not stripped during evaluation of (list ''1 ''2 ''3 ''4 ''5).
; It cannot be! We'll make another test to confirm our suspects!
; I'll replace ' with quote to catch interpreter "in act."

(println (apply '+ (list (quote (quote 1)) (quote (quote 2)))))

; ERR: value expected in function + : '(quote 1)

; Here you are! That extra ' is added by interpreter.
; Now we have all we need!

; let's say that
;
;           exprL is expression that evaluate to list,
;                 that if printed looks like
;                 (value1 value2 ... valuen)
;
;           exprf is expression that evaluates to anything
;
; Then,
;

        (apply exprf exprL)

; is equivalent to

        ((eval exprf) 'value1 'value2 ... 'valuen))

; For example

        (apply * (list 1 2 3 4 5))

; is really equivalent to

        ((eval *) '1 '2 '3 '4 '5)

; You didn't seen that eval and those quotes, did you? Maybe you
; did, but I did not.

No comments:

Post a Comment