From: Max Ischenko
Subject: Using LENGTH inside DEFMACRO
Date:
Message-ID: <kdff5a.kgq.ln@cvs>
Hi.
I've defined a macro which doesn't work:
[62]> (defmacro sp (seq start end)
(if (< end 0)
`(subseq ,seq ,start (+ ,(length seq) ,end))
`(subseq ,seq ,start ,end)))
[65]> (sp b 3 -1)
*** - LENGTH: B is not a sequence
Why call (length seq) is not expanded?
Using ,(length (symbol-value seq)) works fine.
In article <·············@cvs>, Max Ischenko wrote:
>
> I've defined a macro which doesn't work:
>
> [62]> (defmacro sp (seq start end)
> (if (< end 0)
> `(subseq ,seq ,start (+ ,(length seq) ,end))
> `(subseq ,seq ,start ,end)))
>
> [65]> (sp b 3 -1)
>
> *** - LENGTH: B is not a sequence
>
> Why call (length seq) is not expanded?
> Using ,(length (symbol-value seq)) works fine.
Maybe you want
... (+ (length ,seq) ,end) ...
Regards,
--
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."
PGP key ID 0x42B32FC9
From: Max Ischenko
Subject: Re: Using LENGTH inside DEFMACRO
Date:
Message-ID: <eauf5a.rds.ln@cvs>
Nils Goesche wrote:
>> [62]> (defmacro sp (seq start end)
>> (if (< end 0)
>> `(subseq ,seq ,start (+ ,(length seq) ,end))
>> `(subseq ,seq ,start ,end)))
> Maybe you want
> ... (+ (length ,seq) ,end) ...
Sorry for being unclear, but I wanted to compute (length seq) at
macro-expansion time.
Max Ischenko <···@malva.com.ua> writes:
> Nils Goesche wrote:
>
> >> [62]> (defmacro sp (seq start end)
> >> (if (< end 0)
> >> `(subseq ,seq ,start (+ ,(length seq) ,end))
> >> `(subseq ,seq ,start ,end)))
> > Maybe you want
>
> > ... (+ (length ,seq) ,end) ...
>
> Sorry for being unclear, but I wanted to compute (length seq) at
> macro-expansion time.
In that case, you need to call the macro with a list, i.e,
(sp (list 1 2 3 4 5 6) 3 -1)
(Actually, it may also be possible to use symbols with a constant
binding.)
You may also look into define-compiler-macro; the HyperSpec
has some examples that are fairly close to what you're trying to do.
--
Raymond Wiker Mail: ·············@fast.no
Senior Software Engineer Web: http://www.fast.no/
Fast Search & Transfer ASA Phone: +47 23 01 11 60
P.O. Box 1677 Vika Fax: +47 35 54 87 99
NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60
Try FAST Search: http://alltheweb.com/
In article <··············@raw.grenland.fast.no>,
Raymond Wiker <·············@fast.no> wrote:
>Max Ischenko <···@malva.com.ua> writes:
>
>> Nils Goesche wrote:
>>
>> >> [62]> (defmacro sp (seq start end)
>> >> (if (< end 0)
>> >> `(subseq ,seq ,start (+ ,(length seq) ,end))
>> >> `(subseq ,seq ,start ,end)))
>> > Maybe you want
>>
>> > ... (+ (length ,seq) ,end) ...
>>
>> Sorry for being unclear, but I wanted to compute (length seq) at
>> macro-expansion time.
>
> In that case, you need to call the macro with a list, i.e,
>
>(sp (list 1 2 3 4 5 6) 3 -1)
Although in that case, SEQ's value will be the list (LIST 1 2 3 4 5 6), so
the length will be 7, not the expected 6. And if you do:
(sp (append '(1 2 3) '(4 5 6)) 3 -1)
the length will be 3, not 6.
>(Actually, it may also be possible to use symbols with a constant
>binding.)
Nope. Remember, when expanding a macro, the subforms are not evaluated.
I suppose you could call CONSTANTP and, if it's true, call EVAL.
--
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Max Ischenko <···@malva.com.ua> writes:
> [62]> (defmacro sp (seq start end)
> (if (< end 0)
> `(subseq ,seq ,start (+ ,(length seq) ,end))
> `(subseq ,seq ,start ,end)))
>
> [65]> (sp b 3 -1)
So when the macro is expanded, <seq> is bound to the symbol b. In the
expansion you try to do (length seq), and it should be no surprise
that lisp responds:
> *** - LENGTH: B is not a sequence
> Why call (length seq) is not expanded?
It is expanded, but macro "calls" don't evaluate arguments like
functions calls do. That's partly what makes them macros.
> Using ,(length (symbol-value seq)) works fine.
It seems to me you want to try (length ,seq), and then realize that
this is probably best implemented as a function rather than a macro.
--
Frode Vatvedt Fjeld
From: Max Ischenko
Subject: Re: Using LENGTH inside DEFMACRO
Date:
Message-ID: <m6uf5a.rds.ln@cvs>
Frode Vatvedt Fjeld wrote:
>> [62]> (defmacro sp (seq start end)
>> (if (< end 0)
>> `(subseq ,seq ,start (+ ,(length seq) ,end))
>> `(subseq ,seq ,start ,end)))
>>
>> [65]> (sp b 3 -1)
>> Why call (length seq) is not expanded?
> It is expanded, but macro "calls" don't evaluate arguments like
> functions calls do. That's partly what makes them macros.
>> Using ,(length (symbol-value seq)) works fine.
> It seems to me you want to try (length ,seq), and then realize that
> this is probably best implemented as a function rather than a macro.
The goal I wanted to achive was to use precomputed seq length (at
expansion time) when calling SUBSEQ. Using (length ,seq) or inlined
function would compute length of the SEQ at run-time which is what I'm
trying to avoid in this exersize.
Max Ischenko <···@malva.com.ua> writes:
> Frode Vatvedt Fjeld wrote:
>
>
>>> [62]> (defmacro sp (seq start end)
>>> (if (< end 0)
>>> `(subseq ,seq ,start (+ ,(length seq) ,end))
>>> `(subseq ,seq ,start ,end)))
>>>
>>> [65]> (sp b 3 -1)
> The goal I wanted to achive was to use precomputed seq length (at
> expansion time) when calling SUBSEQ. Using (length ,seq) or inlined
> function would compute length of the SEQ at run-time which is what
> I'm trying to avoid in this exersize.
In that case the sequence must be known at compile-time. I still say
you should implement this as a function. If you need to increase
performance, declare the funciton to be inlined, in which case a
decent compiler will automatically reduce the conditional and the
(length seq) form to a constant integer whenever seq is a known
sequence.
If your compiler won't do this for you automatically, use a
compiler-macro to achieve the same effect. But know that in general
the compiler will probably have a much better ability to figure out
when seq is a known sequence than any compiler-macro you can write.
In general, I believe macros should not be used to improve performance
in the way you try to. Use defun for functional abstractions (possibly
with appropriate declarations and compiler-macros for performace), and
defmacro for syntactic abstractions.
--
Frode Vatvedt Fjeld
From: Tim Bradshaw
Subject: Re: Using LENGTH inside DEFMACRO
Date:
Message-ID: <ey3adtwmj3a.fsf@cley.com>
* Frode Vatvedt Fjeld wrote:
> In that case the sequence must be known at compile-time. I still say
> you should implement this as a function. If you need to increase
> performance, declare the funciton to be inlined, in which case a
> decent compiler will automatically reduce the conditional and the
> (length seq) form to a constant integer whenever seq is a known
> sequence.
And even so this is a very strange thing to do, except possibly for
lists. LENGTH on any vector type is going to be very fast, certainly
very fast compared to SUBSEQ which has to allocate a whole new vector.
For lists you do end up having to walk the list twice, I suppose.
--tim
From: Max Ischenko
Subject: Re: Using LENGTH inside DEFMACRO
Date:
Message-ID: <pl3i5a.pb3.ln@cvs>
Frode Vatvedt Fjeld wrote:
>> The goal I wanted to achive was to use precomputed seq length (at
>> expansion time) when calling SUBSEQ. Using (length ,seq) or inlined
>> function would compute length of the SEQ at run-time which is what
>> I'm trying to avoid in this exersize.
> In that case the sequence must be known at compile-time. I still say
> you should implement this as a function. If you need to increase
> performance, declare the funciton to be inlined, in which case a
> decent compiler will automatically reduce the conditional and the
> (length seq) form to a constant integer whenever seq is a known
> sequence.
> If your compiler won't do this for you automatically, use a
> compiler-macro to achieve the same effect. But know that in general
> the compiler will probably have a much better ability to figure out
> when seq is a known sequence than any compiler-macro you can write.
> In general, I believe macros should not be used to improve performance
> in the way you try to. Use defun for functional abstractions (possibly
> with appropriate declarations and compiler-macros for performace), and
> defmacro for syntactic abstractions.
Thanks for your explanation.
Actually, I was not going to use SP anyway. ;-)
I'm just playing around clisp toplevel while studying available
documentation.
--