Difference between quote, list when used in equal - common-lisp

I need to know what the difference between quote and a list. For example:
cl-prompt> (equal (first (list * 1 2)) *)
T
cl-prompt> (equal (first '(* 1 2)) *)
NIL
I don't get what's the problem.

When used as a variable * refers to the last result printed to the repl.
CL-USER> (+ 4 4)
8
CL-USER> *
8
In the first one, both asterisks are unquoted, so they are treated as variables rather than symbols (their value being whatever you evaluated before that line). They are the same variable, so of course EQUAL.
CL-USER> (list * 1 2)
(8 1 2)
In the second one, the first asterisk is a quoted symbol, while the second is a variable with the value T. The symbol * is not EQUAL to T, so it returns NIL
CL-USER> '(* 1 2)
(* 1 2)

Related

Problem while defining variables in racket

I am trying to create a recursive function which picks n items from a list returning the picked values and the list without the values, but when I create my variables I get this error:
new-list: unbound identifier in: new-list
Here is my code:
(define(pick-randomr list n picked) ;;Picked always called as empty list
(if(= n 0) (values list picked)
((let* ([aux list]
[r (random (length aux))]
[value (list-ref aux r)]
[new-picked (cons value picked)]
[new-list (values (remove value aux))])
(values aux r new-list))
(pick-randomr new-list (- n 1) new-picked))))
EDIT:
The line that goes:
(values aux r new-list)
is just to not have an empty body
There are a couple of problems with your syntax:
You should not use list as a parameter name, it conflicts with a built-in procedure of the same name.
Don't surround let* with two brackets, that's a common mistake, brackets are not like curly braces in other languages, you must not use them to define a block of statements, use begin for that - but we don't need it in this particular case.
The first error you got stated that you must not define a let* with an empty body. But the expression you added there isn't right, you must write the expressions that use the variables inside the let*, otherwise the new-list variable won't be visible.
This is what you meant to write:
(define (pick-randomr lst n picked)
(if (= n 0)
(values lst picked)
(let* ([aux lst]
[r (random (length aux))]
[value (list-ref aux r)]
[new-picked (cons value picked)]
[new-list (values (remove value aux))])
(pick-randomr new-list (- n 1) new-picked))))
Let's test it:
(pick-randomr '(1 2 3 4 5) 2 '())
=> '(1 2 5)
'(3 4)

Multiple return values of floor in dotimes

The floor Hyperspec article on dotimes has this example:
(defun palindromep (string &optional
(start 0)
(end (length string)))
(dotimes (k (floor (- end start) 2) t)
(unless (char-equal (char string (+ start k))
(char string (- end k 1)))
(return nil))))
If floor returns two values, e.g. (floor 5 2) -> 2 and 1, how does dotimes know to just use the first value and disregard the second for its count-form?
It's a general mechanism and not specific to dotimes.
If one calls a function or sets a variable, then only the first value will be passed:
CL-USER 52 > (defun foo (x) x)
FOO
CL-USER 53 > (foo (floor 5 2))
2
CL-USER 54 > (let ((foo (floor 5 2)))
foo)
2
To do the equivalent (calling functions, binding variables) with multiple values, one needs to use special constructs:
CL-USER 55 > (multiple-value-call #'list
(floor 5 2) (floor 7 3))
(2 1 2 1)
CL-USER 56 > (multiple-value-bind (foo0 foo1)
(floor 5 2)
(list foo0 foo1))
(2 1)
From 7.10.1,
Normally multiple values are not used. Special forms are required both to produce multiple values and to receive them. If the caller of a function does not request multiple values, but the called function produces multiple values, then the first value is given to the caller and all others are discarded; if the called function produces zero values, then the caller gets nil as a value.
Unless you specifically do something to deal with the multiple values (such as by multiple-value-call or one of the various macros equipped to handle them), all except the first value will be ignored.

COND clause with test only

When COND is given only one test clause and nothing else at all it always returns the test result:
CL-USER> (cond (t))
T
CL-USER> (cond ((> 5 10)))
NIL
Isn't COND just a way to write IF statements?
This doesn't hold for this as when rewriting COND with test only:
CL-USER> (if (> 5 1))
error while parsing arguments to DESTRUCTURING-BIND:
too few elements in
((> 5 1))
to satisfy lambda list
(SB-IMPL::TEST SB-IMPL::THEN &OPTIONAL SB-IMPL::ELSE):
between 2 and 3 expected, but got 1
If it is this way then how does COND exactly transform every clause into IF version?
When COND is given only one test clause and nothing else at all it always returns the test result:
That's right. According to the HyperSpec entry on cond:
results---the values of the forms in the first clause whose test-form yields true, or the primary value of the test-form if there are no forms in that clause, or else nil if no test-form yields true.
Isn't COND just a way to write IF statements?
Well, cond is declared to be a macro, and if to be a special operator, so you can think of it that way, although the expansion of cond isn't defined specifically. But if is defined with syntax that requires a then-part, whereas cond isn't. Here's what a cond clause with no forms expands to (in SBCL):
CL-USER> (pprint (macroexpand '(cond ((+ 2 3)))))
(LET ((#:G1013 (+ 2 3)))
(IF #:G1013
#:G1013
(COND)))
The value of the form is saved in a value and then used as the then-part. When there are forms in the clause, they're wrapped in a progn (which returns the value of its last form):
CL-USER> (pprint (macroexpand
'(cond
((= 2 3) 42 78)
((+ 2 3))
((= 4 5) (print 'something-else)))))
(IF (= 2 3)
(PROGN 42 78)
(COND ((+ 2 3)) ((= 4 5) (PRINT 'SOMETHING-ELSE))))

Average using &rest in lisp

So i was asked to do a function i LISP that calculates the average of any given numbers. The way i was asked to do this was by using the &rest parameter. so i came up with this :
(defun average (a &rest b)
(cond ((null a) nil)
((null b) a)
(t (+ (car b) (average a (cdr b))))))
Now i know this is incorrect because the (cdr b) returns a list with a list inside so when i do (car b) it never returns an atom and so it never adds (+)
And that is my first question:
How can i call the CDR of a &rest parameter and get only one list instead of a list inside a list ?
Now there is other thing :
When i run this function and give values to the &rest, say (average 1 2 3 4 5) it gives me stackoverflow error. I traced the funcion and i saw that it was stuck in a loop, always calling the function with the (cdr b) witch is null and so it loops there.
My question is:
If i have a stopping condition: ( (null b) a) , shouldnt the program stop when b is null and add "a" to the + operation ? why does it start an infinite loop ?
EDIT: I know the function only does the + operation, i know i have to divide by the length of the b list + 1, but since i got this error i'd like to solve it first.
(defun average (a &rest b)
; ...
)
When you call this with (average 1 2 3 4) then inside the function the symbol a will be bound to 1 and the symbol b to the proper list (2 3 4).
So, inside average, (car b) will give you the first of the rest parameters, and (cdr b) will give you the rest of the rest parameters.
But when you then recursively call (average a (cdr b)), then you call it with only two arguments, no matter how many parameters where given to the function in the first place. In our example, it's the same as (average 1 '(3 4)).
More importantly, the second argument is now a list. Thus, in the second call to average, the symbols will be bound as follows:
a = 1
b = ((3 4))
b is a list with only a single element: Another list. This is why you'll get an error when passing (car b) as argument to +.
Now there is other thing : When i run this function and give values to the &rest, say (average 1 2 3 4 5) it gives me stackoverflow error. I traced the funcion and i saw that it was stuck in a loop, always calling the function with the (cdr b) witch is null and so it loops there. My question is:
If i have a stopping condition: ( (null b) a) , shouldnt the program stop when b is null and add "a" to the + operation ? why does it start an infinite loop ?
(null b) will only be truthy when b is the empty list. But when you call (average a '()), then b will be bound to (()), that is a list containing the empty list.
Solving the issue that you only pass exactly two arguments on the following calls can be done with apply: It takes the function as well as a list of parameters to call it with: (appply #'average (cons a (cdr b)))
Now tackling your original goal of writing an average function: Computing the average consists of two tasks:
Compute the sum of all elements.
Divide that with the number of all elements.
You could write your own function to recursively add all elements to solve the first part (do it!), but there's already such a function:
(+ 1 2) ; Sum of two elements
(+ 1 2 3) ; Sum of three elements
(apply #'+ '(1 2 3)) ; same as above
(apply #'+ some-list) ; Summing up all elements from some-list
Thus your average is simply
(defun average (&rest parameters)
(if parameters ; don't divide by 0 on empty list
(/ (apply #'+ parameters) (length parameters))
0))
As a final note: You shouldn't use car and cdr when working with lists. Better use the more descriptive names first and rest.
If performance is critical to you, it's probably best to fold the parameters (using reduce which might be optimized):
(defun average (&rest parameters)
(if parameters
(let ((accum
(reduce #'(lambda (state value)
(list (+ (first state) value) ;; using setf is probably even better, performance wise.
(1+ (second state))))
parameters
:initial-value (list 0 0))))
(/ (first accum) (second accum)))
0))
(Live demo)
#' is a reader macro, specifically one of the standard dispatching macro characters, and as such an abbreviation for (function ...)
Just define average*, which calls the usual average function.
(defun average* (&rest numbers)
(average numbers))
I think that Rainer Joswig's answer is pretty good advice: it's easier to first define a version that takes a simple list argument, and then define the &rest version in terms of it. This is a nice opportunity to mention spreadable arglists, though. They're a nice technique that can make your library code more convenient to use.
In most common form, the Common Lisp function apply takes a function designator and a list of arguments. You can do, for instance,
(apply 'cons '(1 2))
;;=> (1 . 2)
If you check the docs, though, apply actually accepts a spreadable arglist designator as an &rest argument. That's a list whose last element must be a list, and that represents a list of all the elements of the list except the last followed by all the elements in that final list. E.g.,
(apply 'cons 1 '(2))
;;=> (1 . 2)
because the spreadable arglist is (1 (2)), so the actual arguments (1 2). It's easy to write a utility to unspread a spreadable arglist designator:
(defun unspread-arglist (spread-arglist)
(reduce 'cons spread-arglist :from-end t))
(unspread-arglist '(1 2 3 (4 5 6)))
;;=> (1 2 3 4 5 6)
(unspread-arglist '((1 2 3)))
;;=> (1 2 3)
Now you can write an average* function that takes one of those (which, among other things, gets you the behavior, just like with apply, that you can pass a plain list):
(defun %average (args)
"Returns the average of a list of numbers."
(do ((sum 0 (+ sum (pop args)))
(length 0 (1+ length)))
((endp args) (/ sum length))))
(defun average* (&rest spreadable-arglist)
(%average (unspread-arglist spreadable-arglist)))
(float (average* 1 2 '(5 5)))
;;=> 3.25
(float (average* '(1 2 5)))
;;=> 2.66..
Now you can write average as a function that takes a &rest argument and just passes it to average*:
(defun average (&rest args)
(average* args))
(float (average 1 2 5 5))
;;=> 3.5
(float (average 1 2 5))
;;=> 2.66..

How can I recursively print the elements of a list twice?

I need to write a recursive function that prints out the elements of a list twice. For example, rdouble '(1 2 3) would print (1 1 2 2 3 3) and rdouble'(1 (2 3) 4) would print (1 1 (2 2 3 3) 4 4).
So far I have:
(defun rdouble(struct)
(cond
((atom struct) struct)
(t (cons (rdouble (car struct)) (cons (car struct)
(rdouble (cdr struct))
)))))
This works fine for the first example but prints
(1 1 (2 2 3 3) (2 3) 4 4)
for the second example. How do I continue to print out each element twice but not reprint (2 3)? What am I doing wrong and how can I fix it?
The expression has THREE different cases:
an atom -> return it
a cons with an atom as the CAR -> double it
a cons with a cons as the CAR -> walk down
Your code handles only two cases, where your second case mixes 2 and 3.
the reason it is causing the problems you are experiencing is that given ((1 2) 3) your code recurses into (1 2), which correctly becomes (1 1 2 2) and then adds (1 2) (being the car in the first call) after the (1 1 2 2) giving ((1 1 2 2) (1 2) ...)
what would be best is to make rdouble always return a list, and append those lists together instead of consing them

Resources