Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(list ...) vs '(...) in Lisp [duplicate]

When I have a function definition make-cd and execute the function to get the wrong answer.

(defun make-cd (title artist rating ripped)
  '(:title title :artist artist :rating rating :ripped ripped))

(add-record (make-cd "Roses" "Kathy Mattea" 7 t))

(:TITLE TITLE :ARTIST ARTIST :RATING RATING :RIPPED RIPPED)

I should have used (list ...) to get a correct answer.

(defun make-cd (title artist rating ripped)
  (list :title title :artist artist :rating rating :ripped ripped))

(add-record (make-cd "Roses" "Kathy Mattea" 7 t))

(:TITLE "Roses" :ARTIST "Kathy Mattea" :RATING 7 :RIPPED T)

Why is this?

like image 774
prosseek Avatar asked May 16 '26 22:05

prosseek


1 Answers

Lisp has symbols as a data structure. Symbols can be used as themselves - as symbols - or as variables in code.

You need to remember the evaluation rules for quoted expressions and function calls:

Evaluation rule for quoted expression: nothing inside a quoted expression is evaluated. The value is returned as is.

Evaluation rule for function calls: with a function call, all arguments are evaluated left-to-right and these results passed to the function. The computation results of the function are being returned.

Creating data:

A quoted symbol:

CL-USER 13 > 'foo
FOO

A quoted list. Nothing inside the quote is evaluated.

CL-USER 14 > '(foo bar)
(FOO BAR)

A nested list, quoted.

CL-USER 15 > '((foo bar) (foo baz))
((FOO BAR) (FOO BAZ))

A freshly created list using the function list. The contents are symbols.

CL-USER 16 > (list 'foo 'bar)
(FOO BAR)

A freshly created nested list:

CL-USER 17 > (list (list 'foo 'bar) (list 'foo 'bar))
((FOO BAR) (FOO BAR))

A freshly created list, using quoted lists as contents:

CL-USER 18 > (list '(foo bar) '(foo bar))
((FOO BAR) (FOO BAR))

Creating data, using variables:

Using the function list with two variables:

CL-USER 19 > (let ((foo 1)
                   (bar 2))
               (list foo bar))
(1 2)

Using a backquoted list. The elements after the comma are evaluated.

CL-USER 20 > (let ((foo 1)
                   (bar 2))
               `(,foo ,bar))
(1 2)

Using a nested backquoted list. The elements after the comma are evaluated.

CL-USER 21 > (let ((foo 1)
                   (bar 2))
               `((,foo ,bar) (,foo ,bar)))
((1 2) (1 2))
like image 89
Rainer Joswig Avatar answered May 19 '26 11:05

Rainer Joswig



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!