'cdadr' on nested data list in lisp - lisp

While studying cons, cdr and car to handle lists I tried following :
(cadr '('(1) '(2)))
'(2)
which gives the second item in the list as expected.
Whereas following gives :
(cdadr '('(1) '(2)))
((2))
How is data being concerted to code and still not giving error?
How was this evaluated?
cdr on '(2) should give nil, which is does. Why not above?
[I am new to both clisp and stackoverflow so pardon me.]

quote is a special operator which returns its single unevaluated argument. The form (quote ...) can be abbreviated using ' as '.... Since the ' is handled by the reader, the form
'('(1) '(2)))
is actually read the same as
(quote ((quote (1)) (quote (2)))
The outermost application quote to the the argument((quote (1)) (quote (2))) returns that argument. The cadr of that argument is the list
(quote (2))
whose first element is the symbol quote, and whose second element is a list of a single element 2.

Because of quotes. You should write (cadr '((1) (2))).
With your list, (caadr '('(1) '(2))) yields QUOTE.
Actually, your list '('(1) '(2)) is really '((quote (1)) (quote (2))), which may show better why you get this result.

Related

the list inside a list of lisp tutorial

I am reading Programming in Emacs Lisp
Here is another list, this time with a list inside of it:
'(this list has (a list inside of it))
I am confused with the nested list, why it has not a prefix quoting as
'(this list has '(a list inside of it))
if not has a prefix `, why it not parse the a as a function?
's-expression is an abbreviation for (quote s-expression): anything inside the s-expression is considered a datum and it is not evaluated.
So,
'(this list has (a list inside of it))
is an abbreviation of:
(quote (this list has (a list inside of it)))
that contains the following list:
(this list has (a list inside of it))
which is the value of the entire quote form since it is not evaluated.
It is easy to verify this by writing:
'(this list has '(a list inside of it))
This, if evaluated, will produce as value the following list:
(this list has (quote (a list inside of it)))
That's one of the slight difficulties in Lisp: a list is data and can also be a program. If you want a list to be data in a Lisp program, you need to quote it.
Lists as such: one can read them with READ
(this list has (a list inside of it))
(this list has no list inside of it)
(+ 1 2)
(1 2 +)
(1 + 2)
(quote (this list has (a list inside of it)))
(quote (this list has (quote (a quote list inside of it))))
(quote quote)
Valid Lisp forms: one can evaluate them with EVAL
(+ 1 2)
Evaluates to -> 3
(quote (+ 1 2))
Evaluates to -> (+ 1 2)
(quote (this list has (a list inside of it)))
Evaluates to -> (this list has (a list inside of it))
(quote quote)
Evaluates to -> quote
This is also a valid Lisp form:
(quote (this list has (quote (a quoted list inside of it))))
It evaluates to:
(this list has (quote (a quoted list inside of it)))

Why does (list 'quote 1) evaluates to '1 instead of 1? [duplicate]

This question already has an answer here:
Why does (list 'quote 'x) evaluate to 'x and not ('x) or (quote 'x)?
(1 answer)
Closed 4 years ago.
I need some enlightenment with the combined use of list and quote.
Here is what I see:
[1]> (list '1)
(1)
Fair enough. (list '1) becomes "('1)" which evaluates to (1) since ' just returns what goes after it.
[2]> (list 'quote 1)
'1
Why not 1, why the ' went unevaluated here because:
[3]> '1
1
As a general question, am I wrong that the evaluation process will try to resolve everything it can find recursively?
Since list is supposed to construct a list of its arguments, it would be quite strange if it were to return a number. Indeed, '1 is a two element list, containing as its elements the symbol quote and the number 1:
CL-USER> (first (list 'quote 1))
QUOTE
CL-USER> (second (list 'quote 1))
1
The reason it appears as '1 rather than (QUOTE 1) is because your Lisp system prints single-element lists that begin with quote specially.
(list '1) becomes "('1)" which evaluates to (1)
This is not correct. As list is an ordinary function, its argument forms are evaluated to give the value of each argument. In this case the form '1 will be evaluated to the value 1, which list will receive as its single argument. There is no evaluation of the return value.
Note, I'm assuming Common Lisp here.
First a few definItions/notes:
something like (list 1) is called a form. A form is a Lisp object meant to be evaluated.
Since it is a list, it is called a compound form.
Since the first element of the compound form is list and it stands for a function, it is called a function form.
The first element of a function form is the function and the rest elements are the arguments.
Printing a quote form
'foo is the same as (quote foo), since the quote character is a reader macro, which converts the form 'foo at read time into (quote foo)
But how is it printed? The can depend on the value of the variable *print-pretty*. If this variable has the value T, then the printer uses the pretty printer.
* *print-pretty*
T
* '(quote 1)
'1
But when we don't use the pretty printer to print result values:
* (setf *print-pretty* nil)
NIL
* '(quote 1)
(QUOTE 1)
Thus Lisp can print the same thing in different ways, depending on its configuration.
Evaluation of function forms
When function forms are evaluated, we already know that the first element is a function and the rest elements are the arguments.
Thus in (list '1) we see:
list is the function
'1 is the only argument
Now each of the arguments are evaluated to values:
'1 is evaluated to 1, since the quote operator just returns the enclosed object. So the result value is 1.
Since all arguments are evaluated we can call list with the argument value 1.
This then returns (1), since list returns a list of all the provided argument values.
The second example
Now let's look at the second example: (list 'quote 1).
We have again a function form with the function list. But now we have two arguments 'quote and 1.
We need to evaluate each argument from left to right.
'quote evaluates to the symbol quote.
1 evaluates to 1, since numbers are self-evaluating like most objects (exceptions are symbols and lists).
So we call the function list with the argument values quote and 1.
List makes a list of its argument values. Thus the result is (quote 1).
Now remember: (quote 1) is the same as '1). Thus the printer may print the latter variant.
So we have a list as a result, which can either be printed as (quote 1) or '1. But that makes otherwise no difference:
CL-USER 7 > (equal (quote (quote 1)) ''1)
T
Evaluation is done once
As a general question, am I wrong that the evaluation process will try to resolve everything it can find recursively?
The result of a form is not again evaluated. Evaluation of is done only once: the form itself is evaluated.

Need help to understand LISP

I am trying to write my own maximum function (with 2 elements in list at present) but getting error while executing simple function as:
(defun max_for_vararg (list)
(if (null list)
(nil))
(if (> (car list) (cdr list))
(car list)
(cdr list)))
Error as:
? (max_for_vararg '(2 4))
> Error: The value (4) is not of the expected type REAL.
> While executing: CCL::>-2, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
I appreciate if someone can help me understand it. Error seems confusing to me as similar function like below is running fine but not returning max value.
(defun max_for_vararg (list)
(if (null list)
(nil))
(if (> (car list))
(car list)
(cdr list)))
Use cadr instead of cdr. Cdr gets you the rest of the list, which is a single element list. Thus, you have to call car on that list (car (cdr list)). Since this is a common thing to want to do, they made cadr a function that evaluates out to that.
There are several errors in you code. I'll give you some pointers on how to improve it.
You try to call a function named nil.
The first if has a consequence that does (nil), thus call nil as if it is a defined function. nil in other positions is the empty list so this might be an error unless you have made a function called nil.
The first if is dead code
As long as the result of the first if does not throw you into the debugger, the second if will run. Thus when the first if is fixed it will be redundant code. You really should try to have both a consequence and an alternative even though the standard doesn't require it.
(if test-1 ; predicate
test-1-true-expression ; consequent
test-1-false-expression) ; alternative
The second if should of course be one of those expressions and not something that happens unconditional to the first.
In the updated code > needs at least two arguments to be useful.
You can think of > as a function that tests if all the arguments are in descending order. (> 4) is T since all arguments are in descending order. If you find car, cadr and caddr cryptic you may want to try the aliases first, second, third instead. eg
(> (first list) (second list)) ; is first element greater than second element?

emacs lisp pcase error

I am having a hard time reading/understanding the syntax of the pcase statement in emacs-lisp. Please help me figure out how to make the following a valid pcase statement.
(defun execute-play (str)
(setq parse (mapcar (lambda (s) (split-string s ":")) (split-string str " ")))
(pcase (string-to-char (caar parse))``
((pred (<= (string-to-char "5"))) (t-to-pparse))
((pred (<= (string-to-char "d"))) (f-to-p parse))
((string-to-char "w") (w-to-p parse))
(_ "bad input")))
Note that typical input is "1:2 3" or "a 5".
The error from emacs that I get is: 'edebug-signal: Unknown upattern '(string-to-char w)'
This is the second to last case, -- I thought that this would just match the value of (caar parse) against (string-to-char "w") if it did not already match a case before this. Note that I also tried replacing (string-to-char "w") with (SELFQUOTING (string-to-char "w")) since the documentation says that: SELFQUOTING matches itself. This includes keywords, numbers, and strings.
Please help me get this emacs-lisp pcase statement working -- Thanks for all the help!
There are multiple issues with your code:
Since you're not doing any binding or deconstruction in your patterns, you don't need pcase — the conditional is better written using cond.
You have a spurious pair of backquotes at the end of line 3.
You appear to have inverted the first two tests — the first clause will match if the expression is larger than ?5, so the remaining clauses will never match.
pcase doesn't seem to support matching against evaluated values, so third clause should be written (pred (equal (string-to-char "0"))).

Lisp Coerce and Set function explanation

I try to do this directly to the interpret:
(setf example (coerce "blablabla" 'list))
and works fine. Infact (car example) returns #\b
but if I try this:
(defun myfun (string) ( (setf example (coerce string 'list))))
(myfun "blablabla")
I don't get the same!
How can I fix?
Remove the extra parentheses around the setf in the defun:
(defun myfun (string)
(setf example (coerce string 'list)))
Now you'll get the same. Note that the outer parenthesis have meaning. In Lisp, either it is quoted, or must be a function call. If the first element is, as in this case, a list, it cannot be a function to call, hence the error.