Distinguishing an integer from a string vector - common-lisp

I am trying to dispatch on the type of an array. Here's a test case:
(defun column-summary2 (column)
(typecase column
(simple-double-float-vector (format t "Column is a simple-double-float-vector~%"))
;; (simple-integer-vector (format t "Column is a simple-integer-vector~%"))
;; (simple-string-vector (format t "Column is a simple-string-vector~%"))
((simple-array string (*)) (format t "~A Column is a string-array~%" column))
((simple-array float (*)) (format t "~A is a simple-float-array~%" column))
((simple-array integer (*)) (format t "~A is a simple-float-array~%" column))
(bit-vector (make-bit-vector-summary :length (length column) :count (count 1 column))))))
This works as expected for the built in type, bit-vector, and with my own simple-double-float-vector type:
(deftype simple-double-float-vector (&optional (length '*))
"Simple vector of double-float elements."
`(simple-array double-float (,length)))
but fails for string and integer:
LS-USER> (df::column-summary2 #("foo" "bar" "baz"))
#(foo bar baz) Column is a string-array
NIL
LS-USER> (df::column-summary2 #(1 2 3))
#(1 2 3) Column is a string-array
I tried defining types for these two:
(deftype simple-integer-vector (&optional (length '*))
"Simple vector of integer elements."
`(simple-array integer (,length)))
(deftype simple-string-vector (&optional (length '*))
"Simple vector of integer elements."
`(simple-array string (,length)))
Edit: Coerce also seems to fail:
CL-USER> (type-of (coerce #(4 4 1 1 2 1 4 2 2 4 4 3 3 3 4 4 4 1 2 1 1 2 2 4 2 1 2 2 4 6 8 2) '(simple-array integer (32))))
(SIMPLE-VECTOR 32)
CL-USER> (type-of (coerce #("foo" "bar" "baz") '(simple-array string (3))))
(SIMPLE-VECTOR 3)
but it doesn't help. It seems that integer and string are always conflated. Can anyone see why?

typecase can only distinguish types that are implementationally distinct, and it is very unlikely that arrays of integers and strings are. You can test this by, for instance:
(eq (upgraded-array-element-type 'integer)
(upgraded-array-element-type 'string))
Which will very likely return t. And in fact it's likely that upgraded-array-element-type on both these types is itself t: the most specialised array that can store a general string is the same as the one that can store a general integer, since both of these types really require the elements of the array to be general pointers.
The thing here is that when typecase sees an array all it can dispatch on is the implementational type of the array, rather than anything else and those two types are the same in many cases where they are not the same conceptually.

An array's type can only be the type given to make-array as its :element-type, see type simple-array in the spec. If you use array literals, that is likely not the case.
It does not check at runtime the type of each element.
The word can is a hint that this is also influenced by the upgrading of array element types: there is only a fixed set (implementation defined) of array types, mostly determined by whether there is a specialized representation. The actual array element type is the most specialized of that set that fits the declared type.
If you need the exact information at runtime, you need to wrap and tag yourself.

Related

Common Lisp SXHASH and nested lists

The standard says that
(equal x y) implies (= (sxhash x) (sxhash y)). Let us check it:
(defun sxhash-test ()
(let ((obj1 (list 1 2 (list 1 1)))
(obj2 (list 1 2 (list 1 2))))
(format t "are objects equal?: ~a~%" (equal obj1 obj2)) ;; => NIL
(format t "are their hashes equal?: ~a~%"(= (sxhash obj1) (sxhash obj2))))) ;; => T
The function equal works as expected but sxhash doesn't. Could you please explain what I am doing wrong? I use SBCL 2.1.9.
Thank you.
sxhash has to satisfy four requirements:
objects which are equal (and hence objects which are eql, eq, but not necessarily equalp will have the same sxhash value;
the sxhash value of an object must not change during the life of single image unless the object is changed in such a way as to not make it equal to a copy of it before the change;
objects of various types which have a well-defined notion of similarity between images then their sxhash value must be the same in each image.
computation of sxhash must always terminate.
(There is another vague requirement of 'being a good hash code').
(1) means that two objects which are not equal may have the same code but may not, but two objects which are equal must have the same value. A terrible but possible implementation of sxhash would be:
(defun sxhash/terrible (it)
(declare (ignore it))
0)
This fails the 'being a good hash code' test, but that's not something that can really be enforced.
What you are seeing is that two objects which are not equal do have the same sxhash value: that's fine.
Indeed, (1) together with (4) mean that if an implementation is going to compute sxhash on conses in such a way that it walks the graph, then it has to be pretty careful about that: it either needs an occurs check or it needs to only go so deep.
However it is quite possible that sxhash does descend into cons trees. As an example here is LispWorks doing just that:
> (sxhash '(1 2 3))
11890816076270616
> (sxhash '(1 2 3 (4)))
369102953153702944
> (sxhash '(1 2 3 (4)))
740958182301008344
> (sxhash '(1 2 3 (5)))
740958455027237144
> (sxhash '(1 2 3 (5 6)))
741326672350173760
> (sxhash '(1 2 3 (5 (6))))
925006242171775434
Equally it is quite plausible that sxhash treats all instances of a given structure class (or of a given instance of standard-class) as having the same value, because the address of such an object is not constant and there's no obvious place to store the hash code without burning memory. But that's in no way a requirement.
The reason why this effect is observed is that two things are required for the values to be equal:
The two values are the same, meaning that have the same hash.
The two values have the same address
The two lists tested have the same hash, because sxhash doesn't follow nesting. In fact, two structures will always have the same hash.
(sxhash (list 1 2 3)); => 3971322300187561939
(sxhash (list 1 2 3)); => 3971322300187561939 (so, repeatable)
(sxhash (list 1 2 3 (list 4))) ; => 3180777146619076709
(sxhash (list 1 2 3 (list 5))) ; => 3180777146619076709 (ok ...)
Why does `sxhash` return a constant for all structs?
As for equal addresses, if I create two values like 'a they in fact turn out to be one item with one address, and is only stored on the first time that it is seen. Whereas (list 1 2 (list 1 1)) and (list 1 2 (list 1 2)) are different things and are stored at separate addresses.
(sb-kernel:get-lisp-obj-address 'a) ; => 68772678703
(sb-kernel:get-lisp-obj-address 'a) ; => 68772678703 (same...)
(sb-kernel:get-lisp-obj-address (list 1 2 3 (list 4))) ; => 68772925863
(sb-kernel:get-lisp-obj-address (list 1 2 3 (list 5))) ; => 68772805335
Testing these two lists for equality pass using sxhash, but fail with different addresses.

How to protect vector from resizing?

So I am going through Practical Common Lisp once again and I cannot really understand how to create a vector with constant size.
According to the book:
However, even a vector with a fill pointer isn't completely resizable. The vector *x* can hold at most five elements. To make an arbitrarily resizable vector, you need to pass MAKE-ARRAY another keyword argument: :adjustable.
However when I use (vector-push-extend) I can extend my initial vector even when I set :adjustable nil (or leave it default).
(vector-push 'a *x*) ;; 0
(vector-push 'b *x*) ;; 1
(vector-push 'c *x*) ;; 2
(vector-push 'd *x*) ;; 3
(vector-push 'e *x*) ;; 4
*x* ;; #(A B C D E)
(vector-push 'f *x*) ;; NIL
*x* ;; #(A B C D E)
(vector-push-extend 'f *x*) ;; 5
*x* ;; #(A B C D E F)
I assumed that (vector-push-extend) cannot resize array which is not :adjustable? What is the correct way of creating non-dynamic (non-adjustable) array?
The behavior is implementation specific.
The Common Lisp specification says:
There is no specified way to create an array for which adjustable-array-p definitely returns false.
An implementation may make vectors adjustable, even though the :adjustable argument to make-array is given as nil.
To see if an array object is actually adjustable, one needs to call adjustable-array-p.
The Common Lisp standard says that a vector is expressly adjustable (and thus also actually adjustable if it was requested to be so. If it wasn't request, the vector can still be adjustable, actually adjustable.
So the :adjustable nil arg is just telling Lisp, that it can make the vector non-adjustable, if possible.
Here in SBCL:
1) A normal vector is not adjustable:
* (make-array 5)
#(0 0 0 0 0)
* (adjustable-array-p *)
NIL
2) A vector with a fill-pointer is actually adjustable in SBCL:
* (make-array 5 :fill-pointer 0)
#()
* (adjustable-array-p *)
T
3) A vector with a fill-pointer is actually adjustable in SBCL, even though the :adjustable arg was given as nil:
* (make-array 5 :fill-pointer 0 :adjustable nil)
#()
* (adjustable-array-p *)
T
That's in SBCL. In LispWorks 2) and 3) would not be actually adjustable.
The specification of make-array says that it is implementation dependent whether an array with :adjustable nil is actually adjustable. In the notes, it goes on to say:
There is no specified way to create an array for which adjustable-array-p definitely returns false.
So, it really depends on the implementation.
The correct way is to use vector-push if you do not want to extend.

Get value of symbol without evaluating it

It is possible to get value of the symbol unevaluated like this:
(let ((form '(+ 1 2))) `',form)
This expression evaluates to the following:
'(+ 1 2)
Is there some way to do the same thing but without using backquote?
(let ((form '(+ 1 2))) (list 'quote form))
If form is really a constant:
(list 'quote (list '+ '1 '2))
The quotes on 1 and 2 are redundant, since they're literals, but they are informative and are already there in case you replace then with actual expressions.
You can use the longer syntax if you want. Let's see how your form is read and evaluated, step-by-step.
(let ((form '(+ 1 2))) `',form)
Apostrophe is quote:
(let ((form '(+ 1 2))) `(quote ,form))
Backquote/comma (quasiquote) is a shorthand for building data:
(let ((form '(+ 1 2))) (list 'quote form))
Evaluate the let binding, which associates form with its value, literally the list (+ 1 2), inside the lexical environment of this expression:
(list 'quote form)
Te above builds a list made of the quote symbol and the current value bound to form. The above results in a list starting with quote and a sublist, which prints as follows:
(quote (+ 1 2))
... which admits this simpler representation:
'(+ 1 2)
So you can use (list 'quote form) if you prefer, but this is not much different.
(let ((form '(+ 1 2))) `',form)
You ask:
It is possible to get value of the symbol unevaluated...
Actually this not really what it does. By default Common Lisp has local variables using lexical bindings, not symbols having values. Above form computes the value of the variable form, not of the symbol form. The value of form is the list (+ 1 2). With the backquoted quote, you put a list (quote ...) around it. Which gets printed as (QUOTE (+ 1 2)) or '(+ 1 2).
Note that Common Lisp has no way to get from a symbol to the value of a lexical binding. In the source code symbols denote variables, but at runtime we have lexical bindings and not associations from symbols to values.

common lisp how to set an element in a 2d array?

I think I just use setq (or setf, I'm not really sure the difference), but I don't understand how to reference the [i][j]-th element in an array in lisp.
My start condition is this:
? (setq x (make-array '(3 3)))
#2A((0 0 0) (0 0 0) (0 0 0))
I want to alter, say, the 2nd item of the 3rd "row" to give this:
? ;;; What Lisp code goes here?!
#2A((0 0 0) (0 0 0) (0 "blue" 0))
The following, which I would have thought close, gives an error:
(setq (nth 1 (nth 2 x)) "blue")
So what's the correct syntax?
Thanks!
I think proper way is to use setf with aref like this:
(setf (aref x 2 1) "blue")
For more details see reference.
You can find a dictionary of the ARRAY operations in the Common Lisp HyperSpec (the web version of the ANSI Common Lisp standard:
http://www.lispworks.com/documentation/lw50/CLHS/Body/c_arrays.htm
AREF and (SETF AREF) are documented here:
http://www.lispworks.com/documentation/lw50/CLHS/Body/f_aref.htm
The syntax to set an array element is: (setf (aref array &rest subscripts) new-element).
Basically if you want to set something in Common Lisp, you just need to know how to get it:
(aref my-array 4 5 2) ; access the contents of an array at 4,5,2.
Then the set operation is schematically:
(setf <accessor code> new-content)
This means here:
(setf (aref my-array 4 5 2) 'foobar) ; set the content of the array at 4,5,2 to
; the symbol FOOBAR
The correct invocation is
(setf (aref x 2 1) "blue")
setq is used when you're assigning to a variable. Only setf knows how to "reach into" compound objects as with setting a value in your array. Of course, setf also knows how to assign to variables, so if you stick with setf you'll always be okay.

Difference between `set`, `setq`, and `setf` in Common Lisp?

What is the difference between "set", "setq", and "setf" in Common Lisp?
Originally, in Lisp, there were no lexical variables -- only dynamic ones. And
there was no SETQ or SETF, just the SET function.
What is now written as:
(setf (symbol-value '*foo*) 42)
was written as:
(set (quote *foo*) 42)
which was eventually abbreviavated to SETQ (SET Quoted):
(setq *foo* 42)
Then lexical variables happened, and SETQ came to be used for assignment to them too -- so it was no longer a simple wrapper around SET.
Later, someone invented SETF (SET Field) as a generic way of assigning values to data structures, to mirror the l-values of other languages:
x.car := 42;
would be written as
(setf (car x) 42)
For symmetry and generality, SETF also provided the functionality of SETQ. At this point it would have been correct to say that SETQ was a Low-level primitive, and SETF a high-level operation.
Then symbol macros happened. So that symbol macros could work transparently, it was realized that SETQ would have to act like SETF if the "variable" being assigned to was really a symbol macro:
(defvar *hidden* (cons 42 42))
(define-symbol-macro foo (car *hidden*))
foo => 42
(setq foo 13)
foo => 13
*hidden* => (13 . 42)
So we arrive in the present day: SET and SETQ are atrophied remains of older dialects, and will probably be booted from eventual successors of Common Lisp.
(set ls '(1 2 3 4)) => Error - ls has no value
(set 'ls '(1 2 3 4)) => OK
(setq ls '(1 2 3 4)) => OK - make ls to (quote ls) and then have the usual set
(setf ls '(1 2 3 4)) => OK - same as setq so far BUT
(setf (car ls) 10) => Makes ls '(10 2 3 4) - not duplicated by setq/set
You can use setf in place of set or setq but not vice versa since setf can also set the value of individual elements of a variable if the variable has individual elements. See the exaples below:
All four examples will assign the list (1, 2, 3) to the variable named foo.
(set (quote foo) (list 1 2 3)) ;foo => (1 2 3)
(1 2 3)
(set 'foo '(1 2 3)) ;foo => (1 2 3) same function, simpler expression
(1 2 3)
(setq foo '(1 2 3)) ;foo => (1 2 3) similar function, different syntax
(1 2 3)
(setf foo '(1 2 3)) ;foo => (1 2 3) more capable function
(1 2 3)
setf has the added capability of setting a member of the list in foo to a new value.
foo ;foo => (1 2 3) as defined above
(1 2 3)
(car foo) ;the first item in foo is 1
1
(setf (car foo) 4) ;set or setq will fail since (car foo) is not a symbol
4
foo ;the fist item in foo was set to 4 by setf
(4 2 3)
However, you can define a symbol macro that reprents a single item within foo
(define-symbol-macro foo-car (car foo)) ; assumes FOO => (1 2 3)
FOO-CAR
foo-car ;foo-car is now a symbol for the 1st item in foo
1
(setq foo-car 4) ;set or setq can set the symbol foo-car
4
foo ;Lisp macros are so cool
(4 2 3)
You can use defvar if you have not already defined the variable and do not want to give it a value until later in your code.
(defvar foo2)
(define-symbol-macro foo-car (car foo2))
setq is just like set with a quoted first arg -- (set 'foo '(bar baz)) is just like (setq foo '(bar baz)). setf, on the other hand, is subtle indeed -- it's like an "indirection". I suggest http://www.n-a-n-o.com/lisp/cmucl-tutorials/LISP-tutorial-16.html as a better way to get started understanding it than any answer here can give... in short, though, setf takes the first argument as a "reference", so that e.g. (aref myarray 3) will work (as the first arg to setf) to set an item inside an array.
One can think of SET and SETQ being low-level constructs.
SET can set the value of symbols.
SETQ can set the value of variables.
Then SETF is a macro, which provides many kinds of setting things: symbols, variables, array elements, instance slots, ...
For symbols and variables one can think as if SETF expands into SET and SETQ.
* (macroexpand '(setf (symbol-value 'a) 10))
(SET 'A 10)
* (macroexpand '(setf a 10))
(SETQ A 10)
So SET and SETQ are used to implement some of the functionality of SETF, which is the more general construct. Some of the other answers tell you the slightly more complex story, when we take symbol macros into account.
I would like to add to previous answers that setf is macro that call specific function depending on what was passed as its first argument.
Compare results of macro expansion of setf with different types of arguments:
(macroexpand '(setf a 1))
(macroexpand '(setf (car (list 3 2 1)) 1))
(macroexpand '(setf (aref #(3 2 1) 0) 1))
For some types of arguments "setf function" will be called:
(defstruct strct field)
(macroexpand '(setf (strct-field (make-strct)) 1))

Resources