If I create a closure like this,
(let ((A (make-array '(10) :initial-element 5)))
(defun h (i)
(aref a i))
(defsetf h (i) (x) `(setf (aref ,a ,i) ,x)))
then, as I expect, (h i) will return the i-th element of a:
(h 1) ;; => 5
(h 2) ;; => 5
Butalthough the setf expansion semes to work and correctly set the i-th element of a, it also produces a warning in SBCL:
(setf (h 1) 10)
; in: SETF (H 1)
; (SETF (AREF #(5 10 5 5 5 5 5 5 5 5) 1) #:G1124)
; --> LET* MULTIPLE-VALUE-BIND LET FUNCALL SB-C::%FUNCALL
; ==>
; ((SETF AREF) #:NEW0 #(5 10 5 5 5 5 5 5 5 5) 1)
;
; caught WARNING:
; Destructive function (SETF AREF) called on constant data.
; See also:
; The ANSI Standard, Special Operator QUOTE
; The ANSI Standard, Section 3.2.2.3
;
; compilation unit finished
; caught 1 WARNING condition
In GCL an error is signalled:
>(setf (h 1) 10)
Error:
Fast links are on: do (si::use-fast-links nil) for debugging
Signalled by LAMBDA-CLOSURE.
Condition in LAMBDA-CLOSURE [or a callee]: INTERNAL-SIMPLE-UNBOUND-VARIABLE: Cell error on A: Unbound variable:
Broken at LIST. Type :H for Help.
1 Return to top level.
In CLISP and ECL, the example works just fine.
I am returning to Common Lisp after writing Scheme for a couple of years, so I may be mixing the two languages, conceptually. I suppose I have triggered behavior that is undefined according to the spec, but I can't see exactly what I did wrong. I would appreciate any help with this!
Your Problem
It is often instructive to try macroexpand:
(macroexpand '(setf (h 2) 7))
==>
(LET* ()
(MULTIPLE-VALUE-BIND (#:G655)
7
(SETF (AREF #(5 5 5 5 5 5 5 5 5 5) 2) #:G655)))
As you can see, your setf call expands into a form which calls setf on a literal array which is a bad idea in general and, in fact, this is precisely what SBCL is warning you about:
Destructive function (SETF AREF) called on constant data.
Note that despite the warning SBCL (and other conformant implementations like CLISP and ECL) will do what you expect them to do.
This is because the literal array is referred to by the local variable which is accessible to the function h.
Solution
I suggest that you use a function instead
(let ((A (make-array '(10) :initial-element 5)))
(defun h (i)
(aref a i))
(defun (setf h) (x i)
(setf (aref a i) x)))
Related
I am struggling to find the right approach to solve the following function
(FOO #'– '(1 2 3 4 5))
=> ((–1 2 3 4 5) (1 –2 3 4 5) (1 2 –3 4 5) (1 2 3 –4 5) (1 2 3 4 –5))
The first Parameter to the foo function is supposed to be a function "-" that has to be applied to each element returning a list of list as shown above. I am not sure as to what approach I can take to create this function. I thought of recursion but not sure how I will preserve the list in each call and what kind of base criteria would I have. Any help would be appreciated. I cannot use loops as this is functional programming.
It's a pity you cannot use loop because this could be elegantly solved like so:
(defun foo (fctn lst)
(loop
for n from 0 below (length lst) ; outer
collect (loop
for elt in lst ; inner
for i from 0
collect (if (= i n) (funcall fctn elt) elt))))
So we've got an outer loop that increments n from 0 to (length lst) excluded, and an inner loop that will copy verbatim the list except for element n where fctn is applied:
CL-USER> (foo #'- '(1 2 3 4 5))
((-1 2 3 4 5) (1 -2 3 4 5) (1 2 -3 4 5) (1 2 3 -4 5) (1 2 3 4 -5))
Replacing loop by recursion means creating local functions by using labels that replace the inner and the outer loop, for example:
(defun foo (fctn lst)
(let ((len (length lst)))
(labels
((inner (lst n &optional (i 0))
(unless (= i len)
(cons (if (= i n) (funcall fctn (car lst)) (car lst))
(inner (cdr lst) n (1+ i)))))
(outer (&optional (i 0))
(unless (= i len)
(cons (inner lst i) (outer (1+ i))))))
(outer))))
Part of the implementation strategy that you choose here will depend on whether you want to support structure sharing or not. Some of the answers have provided solutions where you get completely new lists, which may be what you want. If you want to actually share some of the common structure, you can do that too, with a solution like this. (Note: I'm using first/rest/list* in preference to car/car/cons, since we're working with lists, not arbitrary trees.)
(defun foo (operation list)
(labels ((foo% (left right result)
(if (endp right)
(nreverse result)
(let* ((x (first right))
(ox (funcall operation x)))
(foo% (list* x left)
(rest right)
(list* (revappend left
(list* ox (rest right)))
result))))))
(foo% '() list '())))
The idea is to walk down list once, keeping track of the left side (in reverse) and the right side as we've gone through them, so we get as left and right:
() (1 2 3 4)
(1) (2 3 4)
(2 1) (3 4)
(3 2 1) (4)
(4 3 2 1) ()
At each step but the last, we take the the first element from the right side, apply the operation, and create a new list use revappend with the left, the result of the operation, and the rest of right. The results from all those operations are accumulated in result (in reverse order). At the end, we simply return result, reversed. We can check that this has the right result, along with observing the structure sharing:
CL-USER> (foo '- '(1 2 3 4 5))
((-1 2 3 4 5) (1 -2 3 4 5) (1 2 -3 4 5) (1 2 3 -4 5) (1 2 3 4 -5))
By setting *print-circle* to true, we can see the structure sharing:
CL-USER> (setf *print-circle* t)
T
CL-USER> (let ((l '(1 2 3 4 5)))
(list l (foo '- l)))
((1 . #1=(2 . #2=(3 . #3=(4 . #4=(5))))) ; input L
((-1 . #1#)
(1 -2 . #2#)
(1 2 -3 . #3#)
(1 2 3 -4 . #4#)
(1 2 3 4 -5)))
Each list in the output shares as much structure with the original input list as possible.
I find it easier, conceptually, to write some of these kind of functions recursively, using labels, but Common Lisp doesn't guarantee tail call optimization, so it's worth writing this iteratively, too. Here's one way that could be done:
(defun phoo (operation list)
(do ((left '())
(right list)
(result '()))
((endp right)
(nreverse result))
(let* ((x (pop right))
(ox (funcall operation x)))
(push (revappend left (list* ox right)) result)
(push x left))))
The base case of a recursion can be determined by asking yourself "When do I want to stop?".
As an example, when I want to compute the sum of an integer and all positive integers below it, I can do this recusively with a base case determined by answering "When do I want to stop?" with "When the value I might add in is zero.":
(defun sumdown (val)
(if (zerop val)
0
(+ (sumdown (1- val)) val)))
With regard to 'preserve the list in each call', rather than trying to preserve anything I would just build up a result as you go along. Using the 'sumdown' example, this can be done in various ways that are all fundamentally the same approach.
The approach is to have an auxiliary function with a result argument that lets you build up a result as you recurse, and a function that is intended for the user to call, which calls the auxiliary function:
(defun sumdown1-aux (val result)
(if (zerop val)
result
(sumdown1-aux (1- val) (+ val result))))
(defun sumdown1 (val)
(sumdown1-aux val 0))
You can combine the auxiliary function and the function intended to be called by the user by using optional arguments:
(defun sumdown2 (val &optional (result 0))
(if (zerop val)
result
(sumdown2 (1- val) (+ val result))))
You can hide the fact that an auxiliary function is being used by locally binding it within the function the user would call:
(defun sumdown3 (val)
(labels ((sumdown3-aux (val result)
(if (zerop val)
result
(sumdown3-aux (1- val) (+ val result)))))
(sumdown3-aux val 0)))
A recursive solution to your problem can be implemented by answering the question "When do I want to stop when I want to operate on every element of a list?" to determine the base case, and building up a result list-of-lists (instead of adding as in the example) as you recurse. Breaking the problem into smaller pieces will help - "Make a copy of the original list with the nth element replaced by the result of calling the function on that element" can be considered a subproblem, so you might want to write a function that does that first, then use that function to write a function that solves the whole problem. It will be easier if you are allowed to use functions like mapcar and substitute or substitute-if, but if you are not, then you can write equivalents yourself out of what you are allowed to use.
Say, we would like to use a function that requires a predicate, but for some reason we're interested in other features of the function (like :start and :end parameters), so we need to supply a predicate, that always returns true.
Obviously, it's not a problem at all:
CL-USER> (defparameter *list* '(0 1 2 3 4 5))
*LIST*
CL-USER> (remove-if (lambda (x) t) *list* :start 1 :end 3)
(0 3 4 5)
Works, but not beautifully at all. And we may get ugly message that variable x is not used. Since I'm in LISP for beauty, I'm curious if there is a 'always t' predicate?
We can define it:
(defun tp (&rest rest)
(declare (ignore rest))
t)
..but may be it exists?
You're looking for the function constantly that takes an argument and returns a function that always returns that value. The predicate you need, then is (constantly t). Thus:
CL-USER> (remove-if (constantly t) '(0 1 2 3 4 5) :start 1 :end 3)
(0 3 4 5)
The notes on constantly show that you were absolutely on the right track with your proposed implementation. (You did even better, though, by adding the (declare (ignore …)).)
Notes:
constantly could be defined by:
(defun constantly (object)
#'(lambda (&rest arguments) object))
After writing this, it occurred to me that this might be a duplicate. I didn't find a proper duplicate, found a similar, more specific, question that was looking to remove a single element at a position, Is there a common lisp macro for popping the nth element from a list?, in which Rainer Joswig's answer includes:
Removing the nth element of a list:
(defun remove-nth (list n)
(remove-if (constantly t) list :start n :end (1+ n)))
This is really just a generalization of that approach, since you're working with arbitrary sequence boundaries. Thus we could have (making the boundary argument analogous to subseq's):
(defun remove-subseq (sequence &optional (start 0) end)
(remove-if (constantly t) sequence :start start :end end))
(defun remove-nth (sequence n)
(remove-subseq sequence n (1+ n)))
CL-USER> (remove-subseq '(0 1 2 3 4 5) 1 3)
(0 3 4 5)
CL-USER> (remove-nth '(0 1 2 3 4 5) 3)
(0 1 2 4 5)
I have two lists: (1 2 3) and (a b) and I need to create something like this (1 2 3 1 2 3). The result is a concatenation of the first list as many times as there are elements in the second. I should use some of the functions (maplist/mapcar/mapcon, etc.). This is exactly what I need, although I need to pass first list as argument:
(mapcan #'(lambda (x) (list 1 2 3)) (list 'a 'b))
;=> (1 2 3 1 2 3)
When I try to abstract it into a function, though, Allegro freezes:
(defun foo (a b)
(mapcan #'(lambda (x) a) b))
(foo (list 1 2 3) (list 'a 'b))
; <freeze>
Why doesn't this definition work?
There's already an accepted answer, but I think some more explanation about what's going wrong in the original code is in order. mapcan applies a function to each element of a list to generate a bunch of lists which are destructively concatenated together. If you destructively concatenate a list with itself, you get a circular list. E.g.,
(let ((x (list 1 2 3)))
(nconc x x))
;=> (1 2 3 1 2 3 1 2 3 ...)
Now, if you have more concatenations than one, you can't finish, because to concatenate something to the end of a list requires walking to the end of the list. So
(let ((x (list 1 2 3)))
(nconc (nconc x x) x))
; ----------- (a)
; --------------------- (b)
(a) terminates, and returns the list (1 2 3 1 2 3 1 2 3 ...), but (b) can't terminate since we can't get to the end of (1 2 3 1 2 3 ...) in order to add things to the end.
Now that leaves the question of why
(defun foo (a b)
(mapcan #'(lambda (x) a) b))
(foo (list 1 2 3) '(a b))
leads to a freeze. Since there are only two elements in (a b), this amounts to:
(let ((x (list 1 2 3)))
(nconc x x))
That should terminate and return an infinite list (1 2 3 1 2 3 1 2 3 ...). In fact, it does. The problem is that printing that list in the REPL will hang. For instance, in SBCL:
CL-USER> (let ((x (list 1 2 3)))
(nconc x x))
; <I manually stopped this, because it hung.
CL-USER> (let ((x (list 1 2 3)))
(nconc x x) ; terminates
nil) ; return nil, which is easy to print
NIL
If you set *print-circle* to true, you can see the result from the first form, though:
CL-USER> (setf *print-circle* t)
T
CL-USER> (let ((x (list 1 2 3)))
(nconc x x))
#1=(1 2 3 . #1#) ; special notation for reading and
; writing circular structures
The simplest way (i.e., fewest number of changes) to adjust your code to remove the problematic behavior is to use copy-list in the lambda function:
(defun foo (a b)
(mapcan #'(lambda (x)
(copy-list a))
b))
This also has an advantage over a (reduce 'append (mapcar ...) :from-end t) solution in that it doesn't necessarily allocate an intermediate list of results.
You could
(defun f (lst1 lst2)
(reduce #'append (mapcar (lambda (e) lst1) lst2)))
then
? (f '(1 2 3) '(a b))
(1 2 3 1 2 3)
Rule of thumb is to make sure the function supplied to mapcan (and destructive friends) creates the list or else you'll make a loop. The same applies to arguments supplied to other destructive functions. Usually it's best if the function has made them which makes it only a linear update.
This will work:
(defun foo (a b)
(mapcan #'(lambda (x) (copy-list a)) b))
Here is some alternatives:
(defun foo (a b)
;; NB! apply sets restrictions on the length of b. Stack might blow
(apply #'append (mapcar #'(lambda (x) a) b))
(defun foo (a b)
;; uses loop macro
(loop for i in b
append a))
I really don't understand why b cannot be a number? You're really using it as church numbers so I think I would have done this instead:
(defun x (list multiplier)
;; uses loop
(loop for i from 1 to multiplier
append list))
(x '(a b c) 0) ; ==> nil
(x '(a b c) 1) ; ==> (a b c)
(x '(a b c) 2) ; ==> (a b c a b c)
;; you can still do the same:
(x '(1 2 3) (length '(a b))) ; ==> (1 2 3 1 2 3)
Essentially I am trying to code up a macro which will print out exactly some statement I am trying to evaluate, and the value it evaluates to.
What I have so far is the following:
(defmacro dbg (statement)
(format t "~a: ~a" statement (eval statement)))
and by typing the following into the slime repl: (dbg (* 2 2)) I get the desired result which is:
"(* 2 2): 4"
However when I try to use it in the following function **:
(defun get-start-position (curr-prime)
(dbg (/ (- (* curr-prime curr-prime) 3) 2))
(/ (- (* curr-prime curr-prime) 3) 2))
slime reports that curr-prime is unbound (and just sticking everything in a let doesn't help). To be more specific the act of trying to compile the function get-start-position results in:
2 compiler notes:
primes.lisp:27:3:
error:
during macroexpansion of (DBG (- # 3)). Use *BREAK-ON-SIGNALS* to intercept:
The variable CURR-PRIME is unbound.
primes.lisp: 29:9:
note:
deleting unreachable code
==>
CURR-PRIME
Compilation failed.
Presumably (and the second warning baffles me), the error comes about because the macro is expanded before the function which calls it gets a chance to bind curr-prime to some value (am I correct here?). That said I have no clue how to get round this issue
What am I doing wrong?
** for what its worth I am coding up a prime sieve where the indicator array has the following elements:
(3,5,7,9, ...)
This particular function will get me the index of the square of a given prime
Not a pro on Lisp macros, but this will do:
(defmacro dbg (statement)
(let ((result (gensym)))
`(let ((,result ,statement))
(format t "~a: ~a" ',statement ,result)
,result)))
then
(dbg (* 2 2))
=> (* 2 2): 4
4
and
(defun get-start-position (curr-prime)
(dbg (/ (- (* curr-prime curr-prime) 3) 2)))
(get-start-position 1)
=> (/ (- (* CURR-PRIME CURR-PRIME) 3) 2): -1
-1
I am learning common lisp and tried to implement a swap value function to swap two variables' value. Why the following does not work?
(defun swap-value (a b)
(setf tmp 0)
(progn
((setf tmp a)
(setf a b)
(setf b tmp))))
Error info:
in: LAMBDA NIL
; ((SETF TMP A) (SETF A B) (SETF B TMP))
;
; caught ERROR:
; illegal function call
; (SB-INT:NAMED-LAMBDA SWAP-VALUE
; (A B)
You can use the ROTATEF macro to swap the values of two places. More generally, ROTATEF rotates the contents of all the places to the left. The contents of the
leftmost place is put into the rightmost place. It can thus be used with more than two places.
dfan is right, this isn't going to swap the two values.
The reason you are getting that error though is that this:
(progn
((setf tmp a)
(setf a b)
(setf b tmp)))
should be this:
(progn
(setf tmp a)
(setf a b)
(setf b tmp))
The first progn has one s-expression in the body, and it's treated
as an application of the function (setf tmp a). In Common Lisp, I
think that only variables or lambda forms can be in the function
position of an application. I could be wrong about the details here,
but I know there are restrictions in CL that aren't in Scheme. That's
why it's an illegal call.
For instance, this is illegal in CL and results in the same error:
CL-USER> ((if (< 1 2) #'+ #'*) 2 3)
; in: LAMBDA NIL
; ((IF (< 1 2) #'+ #'*) 2 3)
;
; caught ERROR:
; illegal function call
;
; compilation unit finished
; caught 1 ERROR condition
You COULD write a swap as a macro (WARNING: I'm a Lisp noob, this
might be a terrible reason for a macro and a poorly written one!)
(defmacro swap (a b)
(let ((tmp (gensym)))
`(progn
(setf ,tmp ,a)
(setf ,a ,b)
(setf ,b ,tmp))))
Nope! Don't do this. Use rotatef as Terje Norderhaug points out.
A function (rather than macro) swapping two special variables can take the variable symbols as arguments. That is, you quote the symbols in the call. Below is an implementation of such a swap function:
(defvar *a* 1)
(defvar *b* 2)
(defun swap-values (sym1 sym2)
(let ((tmp (symbol-value sym1)))
(values
(set sym1 (symbol-value sym2))
(set sym2 tmp))))
? (swap-values '*a* '*b*)
2
1
? *a*
2
Note the use of defvar to define global/special variables and the per convention use of earmuffs (the stars) in their names. The symbol-value function provides the value of a symbol, while set assigns a value to the symbol resulting from evaluating its first argument. The values is there to make the function return both values from the two set statements.
You can not use setf to build a lexical variable tmp. You can use let, as follow:
(defun swap-value (a b)
(let ((tmp 0))
(setf tmp a)
(setf a b)
(setf b tmp))
(values a b))
which will do you hope.
Complimentary to other answers, the OP's targeted problem - the (multiple) value assignment issue - can be solved by parallel assignment using psetf:
(let ((a 21)
(b 42))
(psetf a b
b a)
(print (list a b)))
;; (42 21)