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.

From: Nils Goesche
Subject: Re: Using LENGTH inside DEFMACRO
Date: 
Message-ID: <a5fk1c$74r0s$1@ID-125440.news.dfncis.de>
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.
From: Raymond Wiker
Subject: Re: Using LENGTH inside DEFMACRO
Date: 
Message-ID: <86n0xw8m3p.fsf@raw.grenland.fast.no>
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/
From: Barry Margolin
Subject: Re: Using LENGTH inside DEFMACRO
Date: 
Message-ID: <4POe8.3$Sj3.3080@paloalto-snr1.gtei.net>
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.
From: Frode Vatvedt Fjeld
Subject: Re: Using LENGTH inside DEFMACRO
Date: 
Message-ID: <2hg03ofvrv.fsf@vserver.cs.uit.no>
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.
From: Frode Vatvedt Fjeld
Subject: Re: Using LENGTH inside DEFMACRO
Date: 
Message-ID: <2h7kp0fir1.fsf@vserver.cs.uit.no>
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.


--