[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

Symbol-macro question

Nicolas Neuss

7/24/2015 1:51:00 PM

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))

Thanks,
Nicolas
3 Answers

Kaz Kylheku

7/24/2015 2:26:00 PM

0

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.

Nicolas Neuss

7/24/2015 8:22:00 PM

0

Kaz Kylheku <kaz@kylheku.com> writes:

> 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.

Thank you for the explanation.

I feared that it might not be possible:-( But it is so rare that CL
cannot adapt to my needs that I thought I should ask nevertheless.

Nicolas

Pascal Costanza

7/26/2015 6:27:00 PM

0

On 24/07/2015 22:22, Nicolas Neuss wrote:
> Kaz Kylheku <kaz@kylheku.com> writes:
>
>> 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.
>
> Thank you for the explanation.
>
> I feared that it might not be possible:-( But it is so rare that CL
> cannot adapt to my needs that I thought I should ask nevertheless.

You can try to wrap a more complete form:

(symbol-macrolet ((element-type 'double-float))
(array-let ((a 3 element-type))
a))

....with an appropriate (unhygienic!) definition for array-let that
expands to a let-form with an embedded type declaration.

Pascal

--
My website: http:/...
Common Lisp Document Repository: http://cdr.eu...
Closer to MOP & ContextL: http://common-lisp.net/proje...
The views expressed are my own, and not those of my employer.