Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extendable Vector Type

How does one properly specify the common-lisp type of an extendable vector (ie, acceptable to vector-push-extend), so it can be copied. For example, if a vector is defined by:

(defparameter v (make-array 2
                            :initial-contents '((a (b)) (c (d) e))
                            :adjustable t
                            :fill-pointer t))

My simple (incorrect) approach for copying it is:

(map 'array #'copy-tree v)

but this generates a type error in sbcl. Can a proper sequence type specification make this work?

like image 407
davypough Avatar asked Aug 30 '26 14:08

davypough


2 Answers

Simple copy

You could simply do this:

(map (type-of v) #'copy-tree v)

What is the type?

CL-USER> (type-of v)
(VECTOR T 2)

The following is sufficient:

(map 'vector #'copy-tree v)

This graph is helpful to remember type hierarchies, notably arrays and vectors.

Adjustable, fill-pointer, ...

However, the resulting vectors are not adjustable. Maybe something like this can help:

(defun my-copy (vector)
  (map-into (make-array (array-dimensions vector)
                        :adjustable (adjustable-array-p vector)
                        :fill-pointer (fill-pointer vector))
            #'copy-tree
            vector))
like image 57
coredump Avatar answered Sep 02 '26 05:09

coredump


MAP needs as a result type a sequence type specifier. ARRAY is not one. Examples for subtypes of SEQUENCE are VECTOR and LIST.

The type declaration syntax for a VECTOR is: vector [{element-type | *} [{size | *}]].

There is no way to specify features like adjustable, fill pointer, displacement, ... in a vector type declaration. Corresponding feature options are also not provided as keywords to the function make-sequence. Also copy-seq will not create vectors with such features. To create such vectors you have to use MAKE-ARRAY.

Thus the options are:

  • maybe the vector types are sufficient
  • for vectors with special features, create them via MAKE-ARRAY and use functions like MAP-INTO -> see the excellent answer from coredump.
like image 43
Rainer Joswig Avatar answered Sep 02 '26 05:09

Rainer Joswig