Why can't constants be used as array sizes in Common Lisp specifiers?

At least some implementations of Common Lisp do not allow the use of user-defined constants as array sizes in some type specifiers. For example, in SBCL, this code:

(defconstant +len+ 3)

(defun foo (x) 
  (declare (type (simple-array fixnum (+len+)) x))
  x)

generates this error:

; in: DEFUN FOO
;     (TYPE (SIMPLE-ARRAY FIXNUM (+LEN+)) X)
; 
; caught ERROR:
;   bad dimension in array type: +LEN+

Why? It seems surprising that custom constants cannot be used in type specifiers, since it would be desirable to be able to coordinate multiple type specifiers using some kind of global definition. I understand that type specifiers should be fully understood at compile time. But I would have thought that the compiler would be able to replace the characters defined by defconstanttheir literal values. I would think that this is one of the goals defconstant. (So ​​far, I have not been successful in understanding this issue more deeply from Common Lisp Hyperspec, CLTL2, SBCL's guide, or Google's emergence. I suspect the answer is in one form or another ....)

+4
source share
5

, - :

(defconstant +len+ 3)

(deftype len-3-fixnum-array () `(array fixnum (,+len+)))

(defun foo (x)
  (declare (type len-3-fixnum-array x))
  (print x))

(foo (make-array 3 :element-type 'fixnum))
;; #(0 0 0)

(foo (make-array 4 :element-type 'fixnum))
;; The value #(0 0 0 0) is not of type (VECTOR FIXNUM 3).
;;    [Condition of type TYPE-ERROR]

, - , .


.. , declare, , , , 3, +len+.

+4

2D-:

(defconstant board-width  4)
(defconstant board-height 3)

(setq *board* (make-array '(board-width board-height) :initial-element 0))

The value BOARD-WITH is not of type SB-INT:INDEX.

, :

(setq *board* (make-array (list board-width board-height) :initial-element 0))

.

+4

ANSI CL, . simple-array:

simple-array [{element-type | *} [dimension-spec]]

dimension-spec::= rank | * | ({dimension | *}*) 

:

dimension---a valid array dimension.

element-type---a type specifier.

rank---a non-negative fixnum.

valid array dimension fixnum.

simple-array . . , (- > ).

DEFTYPE .

+3

.

, .

, Lisp , . I.e., , , . C,

int N = 10;
int v[N];

POV , .

+2

, , , , , :

(defun foo (x) 
  (declare (type (simple-array fixnum (#.+len+)) x))
  x)

#.is a standard readmacro that evaluates a value while reading. The Lisp form only sees what has been expanded. http://www.lispworks.com/documentation/HyperSpec/Body/02_dhf.htm

0
source

All Articles