Kaz Kylheku
7/24/2015 2:26:00 PM
On 2015-07-24, Nicolas Neuss <lastname@scipolis.de> wrote:
> Hello,
>
> I wonder if I can somehow make the following work (using a predefined
> number type given as a symbol macro also in the declaration):
>
> (symbol-macrolet ((element-type 'double-float))
> (let ((a (make-array 3 :element-type element-type)))
> (declare (type (simple-array element-type *) a))
> a))
Nope. Declarations aren't forms. Since they aren't forms, they are not
traversed for macro expansions.
If the declaration were so traversed, it still wouldn't work. Your symbol macro
expansion includes the quote, you see: element-type is replaced with (quote
double-float). That works as an argument in make-array, but not as a component
of a derived type expression.
Types, however, are traversed for expansions: namely those introduced
by deftype! The only problem with deftype is that the "macros" it introduces
are global, and not lexically scoped like what you are after.
(deftype df () 'double-float) ;; quote not part of the type!
(let ((a (make-array 3 :element-type 'df))) ;; quote here!
(declare (type (simple-array df *) a))
a))
All that is needed for you is a lexical binding construct which does
the same thing as deftype, over a scope.
;; imaginary
(lettype ((df () 'double-float))
(let ((a (make-array 3 :element-type 'df)))
(declare (type (simple-array df *) a))
a))
Lisp designers don't always introduce a local version of something global,
because they don't anticipate the need. For instance, setf expanders aren't
local. You can't define syntax for a place which is recognized only in some
scope. While uses for that aren't unimaginable, they seem marginal.