From: Paolo Amoroso
Subject: LOOP with fixed final index value
Date: 
Message-ID: <873bb7vgsb.fsf@plato.moon.paoloamoroso.it>
Consider this LOOP form parameterized by the INITIAL and FINAL index
values, and an INCREMENT:

(defun myloop (initial final increment)
  (loop for i = initial then (+ i increment)
        while (<= i final)
        ;; do something with i
        do (print i)))

where INITIAL and FINAL are non negative integers or floats, with
FINAL > INITIAL.  It is called like this:

CL-USER> (myloop 0 10 3)

0 
3 
6 
9 
NIL

I would like the final index value to *always* be the one provided as
the FINAL parameter, like this:

(myloop 0 10 3)

0 
3 
6 
9
10

but I am not able to express this with the LOOP syntax.  Any
suggestions?


Paolo
-- 
Lisp Propulsion Laboratory log - http://www.paoloamoroso.it/log

From: Sam Steingold
Subject: Re: LOOP with fixed final index value
Date: 
Message-ID: <m364g3adhg.fsf@loiso.podval.org>
> * Paolo Amoroso <·······@zpyvax.vg> [2006-09-04 16:37:56 +0200]:
>
> Consider this LOOP form parameterized by the INITIAL and FINAL index
> values, and an INCREMENT:
>
> (defun myloop (initial final increment)
>   (loop for i = initial then (+ i increment)
>         while (<= i final)
>         ;; do something with i
>         do (print i)))
>
> where INITIAL and FINAL are non negative integers or floats, with
> FINAL > INITIAL.  It is called like this:
>
> CL-USER> (myloop 0 10 3)
>
> 0 
> 3 
> 6 
> 9
printed
> NIL
returned

> I would like the final index value to *always* be the one provided as
> the FINAL parameter, like this:
>
> (myloop 0 10 3)
>
> 0 
> 3 
> 6 
> 9
> 10

[12]> (loop :for i :from 0 :to 10 :by 3 :do (print i) :finally (return 10))

0 
3 
6 
9
;; printed
10
;; returned



I don't think I understood your question correctly though...

-- 
Sam Steingold (http://www.podval.org/~sds) on Fedora Core release 5 (Bordeaux)
http://jihadwatch.org http://israelnorthblog.livejournal.com
http://ffii.org http://camera.org http://truepeace.org http://pmw.org.il
There are many reasons not to use Lisp - but no good ones.
From: Paolo Amoroso
Subject: Re: LOOP with fixed final index value
Date: 
Message-ID: <87y7szu09u.fsf@plato.moon.paoloamoroso.it>
Sam Steingold <···@podval.org> writes:

> [12]> (loop :for i :from 0 :to 10 :by 3 :do (print i) :finally (return 10))
>
> 0 
> 3 
> 6 
> 9
> ;; printed
> 10
> ;; returned
>
>
>
> I don't think I understood your question correctly though...

My question is indeed convoluted.  I would like the final value to be
usable as the other index values.  In my example I just printed it,
but I may pass the value as an argument to a function, or something
similar.


Paolo
-- 
Why Lisp? http://wiki.alu.org/RtL%20Highlight%20Film
The Common Lisp Directory: http://www.cl-user.net
From: Ken Tilton
Subject: Re: LOOP with fixed final index value
Date: 
Message-ID: <NmXKg.4$7U4.0@newsfe12.lga>
Paolo Amoroso wrote:
> Consider this LOOP form parameterized by the INITIAL and FINAL index
> values, and an INCREMENT:
> 
> (defun myloop (initial final increment)
>   (loop for i = initial then (+ i increment)
>         while (<= i final)
>         ;; do something with i
>         do (print i)))
> 
> where INITIAL and FINAL are non negative integers or floats, with
> FINAL > INITIAL.  It is called like this:
> 
> CL-USER> (myloop 0 10 3)
> 
> 0 
> 3 
> 6 
> 9 
> NIL
> 
> I would like the final index value to *always* be the one provided as
> the FINAL parameter, like this:
> 
> (myloop 0 10 3)
> 
> 0 
> 3 
> 6 
> 9
> 10
> 
> but I am not able to express this with the LOOP syntax.  Any
> suggestions?

loop syntax is not the problem. Your code says i should move by the 
increment specified, so the only loop that will make i even arrive at 
final, let alone stop there, would have to be a badly broken one. 
(Assuming, as is implicit, that there is no requirement that final fall 
on an even increment.)

You should either express a different stepping of i:

  (loop for i = initial then (+ i (min increment (- final i)))

or leave the stepping as is and use the finally clause to force handling 
of the final value. The problem with this second approach is having to 
reiterate the DO handling in the FINALLY. It is also not so nicely 
self-documenting: that elaborate increment form above maps nicely to the 
unusual "stepping", if we can even call it that.

kt

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Ari Johnson
Subject: Re: LOOP with fixed final index value
Date: 
Message-ID: <m2odtvejo9.fsf@nibbler.theari.com>
Ken Tilton <·········@gmail.com> writes:

> Paolo Amoroso wrote:
>> Consider this LOOP form parameterized by the INITIAL and FINAL index
>> values, and an INCREMENT:
>> (defun myloop (initial final increment)
>>   (loop for i = initial then (+ i increment)
>>         while (<= i final)
>>         ;; do something with i
>>         do (print i)))
>> where INITIAL and FINAL are non negative integers or floats, with
>> FINAL > INITIAL.  It is called like this:
>> CL-USER> (myloop 0 10 3)
>> 0 3 6 9 NIL
>> I would like the final index value to *always* be the one provided
>> as
>> the FINAL parameter, like this:
>> (myloop 0 10 3)
>> 0 3 6 9
>> 10
>> but I am not able to express this with the LOOP syntax.  Any
>> suggestions?
>
> loop syntax is not the problem. Your code says i should move by the
> increment specified, so the only loop that will make i even arrive at
> final, let alone stop there, would have to be a badly broken
> one. (Assuming, as is implicit, that there is no requirement that
> final fall on an even increment.)

Sure it is!  The problem is that LOOP does not do what he wants.  And
anytime Lisp doesn't have what you want is a good opportunity to add
something to it.

(defmacro myloop ((variable initial final &optional (increment 1)) &body body)
  (let ((label (gensym)))
    `(let ((,variable ,initial))
       (tagbody
         ,label
         ,@body
         (when (< ,variable ,final)
           (incf ,variable ,increment)
           (when (> ,variable ,final)
             (setf ,variable ,final))
           (go ,label))))))

(myloop (i 0 10 3)
  (format t "~D~%" i))
 =>
0
3
6
9
10

Making this return something useful is an exercise for the reader.
From: Paolo Amoroso
Subject: Re: LOOP with fixed final index value
Date: 
Message-ID: <87lkoztzye.fsf@plato.moon.paoloamoroso.it>
Ken Tilton <·········@gmail.com> writes:

> one. (Assuming, as is implicit, that there is no requirement that
> final fall on an even increment.)

Indeed.  Regardless of where the final falls, I would like it to
always be the last index value as explained in my reply to Sam in this
thread.


> You should either express a different stepping of i:
>
>   (loop for i = initial then (+ i (min increment (- final i)))

Thanks to you and all those who contributed suggestions.


Paolo
-- 
Why Lisp? http://wiki.alu.org/RtL%20Highlight%20Film
The Common Lisp Directory: http://www.cl-user.net
From: Christophe Rhodes
Subject: Re: LOOP with fixed final index value
Date: 
Message-ID: <sqac5ffzoa.fsf@cam.ac.uk>
Paolo Amoroso <·······@mclink.it> writes:

> I would like the final index value to *always* be the one provided as
> the FINAL parameter, like this:
>
> (myloop 0 10 3)
>
> 0 
> 3 
> 6 
> 9
> 10
>
> but I am not able to express this with the LOOP syntax.  Any
> suggestions?

(defun myloop (initial final increment)
  (loop for i = initial then (+ i increment)
        while (< i final)
        do (print i)
        finally (let ((i final)) (print i))))

Have you simplified your real problem too much?

Christophe
From: Paolo Amoroso
Subject: Re: LOOP with fixed final index value
Date: 
Message-ID: <87u03nu07f.fsf@plato.moon.paoloamoroso.it>
Christophe Rhodes <·····@cam.ac.uk> writes:

> (defun myloop (initial final increment)
>   (loop for i = initial then (+ i increment)
>         while (< i final)
>         do (print i)
>         finally (let ((i final)) (print i))))
>
> Have you simplified your real problem too much?

This is an acceptable solution, thanks.


Paolo
-- 
Why Lisp? http://wiki.alu.org/RtL%20Highlight%20Film
The Common Lisp Directory: http://www.cl-user.net
From: Pascal Costanza
Subject: Re: LOOP with fixed final index value
Date: 
Message-ID: <4m2tmsF47q0iU1@individual.net>
Paolo Amoroso wrote:
> Consider this LOOP form parameterized by the INITIAL and FINAL index
> values, and an INCREMENT:
> 
> (defun myloop (initial final increment)
>   (loop for i = initial then (+ i increment)
>         while (<= i final)
>         ;; do something with i
>         do (print i)))
> 
> where INITIAL and FINAL are non negative integers or floats, with
> FINAL > INITIAL.  It is called like this:
> 
> CL-USER> (myloop 0 10 3)
> 
> 0 
> 3 
> 6 
> 9 
> NIL
> 
> I would like the final index value to *always* be the one provided as
> the FINAL parameter, like this:
> 
> (myloop 0 10 3)
> 
> 0 
> 3 
> 6 
> 9
> 10
> 
> but I am not able to express this with the LOOP syntax.  Any
> suggestions?

Untested:

(loop for i = initial then (+ i increment)
       while (<= i final)
       do (print i)
       finally (when (< (- i increment) final) (print final)))


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Paolo Amoroso
Subject: Re: LOOP with fixed final index value
Date: 
Message-ID: <87psebu05h.fsf@plato.moon.paoloamoroso.it>
Pascal Costanza <··@p-cos.net> writes:

> (loop for i = initial then (+ i increment)
>        while (<= i final)
>        do (print i)
>        finally (when (< (- i increment) final) (print final)))

Another acceptable solution, thanks.


Paolo
-- 
Why Lisp? http://wiki.alu.org/RtL%20Highlight%20Film
The Common Lisp Directory: http://www.cl-user.net