0

If I have a function and also a list of arguments, I can use apply like this:

(apply func args)

For example:

(apply + '(1 2 3))

Now, if I define the function func and a list of arguments args as follows:

(define func +)
(define args '(1 2 3))

why then doesn't the following work to run the function:

(append (list func) args)
(cons func args)          ; same thing
; (#<procedure:+> 1 2 3)

I would think the append would create (+ 1 2 3) just as (append '(1) '(2 3)) creates (1 2 3).

Why doesn't that occur, and is there a way to use append to 'act like' the apply, as I'm trying to do above?

Will Ness
  • 70,110
  • 9
  • 98
  • 181
David542
  • 104,438
  • 178
  • 489
  • 842

1 Answers1

1

It does occur. Both (append (list func) args) and (cons func args) do create the same list, (#<procedure:+> 1 2 3).

But it's just a list, a piece of data. To "run" it, you need to evaluate it:

> (eval (cons func args) (null-environment 5))
6

> (eval (append (list func) args) (null-environment 5))
6
Will Ness
  • 70,110
  • 9
  • 98
  • 181
  • I see, so doing `eval` and `apply` are almost like two sides of the coin, and would be done with: `(apply + '(1 2))` vs `(eval (cons + '(1 2)) )` ? – David542 Jun 21 '21 at 21:23
  • `eval` is pretty tough to use correctly. It works for simple cases like lists of numbers because `1` evaluates to itself, and so there's no difference between `'1` and `1`. But in general you would need to quote the arguments in order for `eval` to be right. – amalloy Jun 22 '21 at 00:57
  • David542, they are so much the two sides of the coin that a famous book has that picture [on its cover](https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html) (in a hand of the wizard there). it also [appears that way](https://stackoverflow.com/a/34910496/849891) in the original 1958 LISP paper by John McCarthy. I believe I also used that in that recent [answer about implementing `apply`](https://stackoverflow.com/a/68037807/849891) by enclosing each already-evaluated value in a `quote` before passing them to `eval`. (indeed; @amalloy) that's why null environment is enough – Will Ness Jun 22 '21 at 07:27