4

ANSI Common Lisp. Why I get an other answer in the last case?

(list 1 2 3 nil) ; (1 2 3 nil)
(funcall (function list) 1 2 3 nil) ; (1 2 3 nil)
(apply (function list) '(1 2 3 nil)) ; (1 2 3 nil)
(apply (function list) 1 2 3 nil) ; (1 2 3)
sigjuice
  • 28,661
  • 12
  • 68
  • 93
Andrey Bushman
  • 11,712
  • 17
  • 87
  • 182

1 Answers1

8

APPLY expects as arguments:

  • a function
  • zero ... n arguments
  • and then a list of arguments at the end

The function will basically be called with the result of (list* 0-arg ... n-arg argument-list)

Note that (list* '(1 2 3)) evaluates to just (1 2 3).

The arguments are called spreadable argument list in Common Lisp.

CL-USER 60 > (apply (function list) 1 2 3 nil)
(1 2 3)

CL-USER 61 > (apply (function list) (list* 1 2 3 nil))
(1 2 3)

CL-USER 62 > (apply (function list) (list* '(1 2 3)))
(1 2 3)

APPLY uses such a spreadable argument list by design. For example (... 1 2 3 '(4 5)). With FUNCALL you have to write the arguments as usual: (... 1 2 3 4 5).

APPLY has a single purpose in Common Lisp: it allows functions to be called with computed argument lists. To make that a bit more convenient, this idea of the spreadable argument list has been used. It works the same for example in Emacs Lisp.

Imagine that you have a list of arguments and you want to add two arguments in front.

CL-USER 64 > (apply '+ args)
60

CL-USER 65 > (apply '+ 1 2 args)
63

CL-USER 66 > (apply '+ (append (list 1 2) args))
63
Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
  • Thank you, but I don't understand still: why I get not the `nil item at the end of list in the last case? I am a beginner in the ANSI Common Lisp, and I am reading the Paul Graham's book now. – Andrey Bushman Jan 10 '14 at 09:01
  • 1
    @bush: last case: NIL is the empty list. `(list* 1 2 3 nil)` is adding 1, 2, 3, to the empty list. Thus `(1 2 3)`. – Rainer Joswig Jan 10 '14 at 09:12