[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.lisp

Re: do loops and idioms

William James

5/10/2015 1:23:00 PM

Erik Naggum wrote:

> | (defun filtered-input (predicate prompt)
> | "Obtain input that passes the predicate"
> | (labels ((local-input ()
> | (format t prompt)
> | (read)))
> | (do ((j (local-input) (local-input)))
> | ((funcall predicate j) j))))
> :
> | It bothers me that I have to repeat myself in my do loop in the
> | definition of j.
> | Is there another idiom in common usage in common LISP?
>
> well, I would do one of these:
>
> (loop initially (format t prompt)
> for local-input = (read)
> until (funcall predicate local-input)
> finally (return local-input))
>
> (do () () ;or `loop'
> (format t prompt)
> (let ((local-input (read)))
> (when (funcall predicate local-input)
> (return local-input))))

.....

> as a matter of user interface design, I think it would make sense to
> indicate that a value was rejected and to use another prompt for repeats:
>
> (defun filtered-input (predicate prompt repeat-prompt)
> (loop initially (format *query-io* prompt)
> for local-input = (read *query-io*)
> until (funcall predicate local-input)
> do (format *query-io* repeat-prompt)
> finally (return local-input)))

Why was (format *query-io* prompt) put inside of the LOOP?
Is it executed more than once? Isn't it executed before
the looping starts? Why wasn't it put outside of the loop?
Putting it inside of the loop accomplishes nothing but
increasing the size of the code.

Worshippers of CL (COBOL-Like) and LOOP are justly
proud of their unmatched mindlessness.


Gauche Scheme:

(define (filtered-input predicate prompt repeat-prompt)
(display prompt) (flush)
(generator-find
(lambda (local-input)
(or (predicate local-input)
(begin (display repeat-prompt) (flush) #f)))
read))

--
You, who wasted your chance, you, who were corrupted and whose souls were
bought, do not try to teach us, for goats cannot teach lions.
http://www.kolumbus.fi/aquilon/aquilon...
4 Answers

Kaz Kylheku

5/11/2015 11:40:00 PM

0

On 2015-05-10, WJ <w_a_x_man@yahoo.com> wrote:
> Erik Naggum wrote:
>>
>> (defun filtered-input (predicate prompt repeat-prompt)
>> (loop initially (format *query-io* prompt)
>> for local-input = (read *query-io*)
>> until (funcall predicate local-input)
>> do (format *query-io* repeat-prompt)
>> finally (return local-input)))
>
> Why was (format *query-io* prompt) put inside of the LOOP?
> Is it executed more than once?

No; it is the argument of an initially clause, which specifies
some evaluation to be done before the first iteration (in the "loop prologue"
part of the expanded form).

> Isn't it executed before
> the looping starts? Why wasn't it put outside of the loop?

For the same reason that i = 0 isn't put outside the loop in

for (i = 0; i < n; i++) ...

"outside the loop construct" isn't where "the looping starts". The looping, as
it were, starts, roughly, when the first test is made which can determine
whether any of the repeated parts of the loop will or will not execute.

(For a simple while loop construct like (while cond body ...), this is indeed
right inside the loop; no execution enclosed in the loop form is prior
to the start of the looping.)

> Putting it inside of the loop accomplishes nothing but
> increasing the size of the code.

It is not obvious that this would be the case, even if it were
executed more than once. Unless you mean, "increases the size of the
source code by the symbol 'initially'", rather than the object code.

The answer to that is that Erik Naggum wasn't the type of coder who worried
about minimizing token count in the source code.

It is tidy to have everything in the loop, even if you have to pay
for that with extra clause keywords to put it all there.

Pascal J. Bourguignon

5/11/2015 11:56:00 PM

0

Kaz Kylheku <kaz@kylheku.com> writes:

> On 2015-05-10, WJ <w_a_x_man@yahoo.com> wrote:
>> Erik Naggum wrote:
>>>
>>> (defun filtered-input (predicate prompt repeat-prompt)
>>> (loop initially (format *query-io* prompt)
>>> for local-input = (read *query-io*)
>>> until (funcall predicate local-input)
>>> do (format *query-io* repeat-prompt)
>>> finally (return local-input)))
>>
>> Why was (format *query-io* prompt) put inside of the LOOP?
>> Is it executed more than once?
>
> No; it is the argument of an initially clause, which specifies
> some evaluation to be done before the first iteration (in the "loop prologue"
> part of the expanded form).
>
>> Isn't it executed before
>> the looping starts? Why wasn't it put outside of the loop?
>
> For the same reason that i = 0 isn't put outside the loop in
>
> for (i = 0; i < n; i++) ...
>
> "outside the loop construct" isn't where "the looping starts". The looping, as
> it were, starts, roughly, when the first test is made which can determine
> whether any of the repeated parts of the loop will or will not execute.
>
> (For a simple while loop construct like (while cond body ...), this is indeed
> right inside the loop; no execution enclosed in the loop form is prior
> to the start of the looping.)
>
>> Putting it inside of the loop accomplishes nothing but
>> increasing the size of the code.
>
> It is not obvious that this would be the case, even if it were
> executed more than once. Unless you mean, "increases the size of the
> source code by the symbol 'initially'", rather than the object code.
>
> The answer to that is that Erik Naggum wasn't the type of coder who worried
> about minimizing token count in the source code.
>
> It is tidy to have everything in the loop, even if you have to pay
> for that with extra clause keywords to put it all there.

Furthermore, I don't know about you, but my programming teachers taught
me to build an iteration by specifying:

- the stop condition,
- the increment,
- the initialization, <--- in :initially, obviously.

and since CL:LOOP allows also to accumulate values and to return a
result, we also have to specify:

- the termination,

and to declare loop variables.

Hence the various clauses of the CL:LOOP macro.


--
__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk

Kenneth Tilton

5/12/2015 12:53:00 PM

0

On Monday, May 11, 2015 at 7:39:43 PM UTC-4, Kaz Kylheku wrote:
> On 2015-05-10, WJ <w_a_x_man@yahoo.com> wrote:
> > Erik Naggum wrote:
> >>
> >> (defun filtered-input (predicate prompt repeat-prompt)
> >> (loop initially (format *query-io* prompt)
> >> for local-input = (read *query-io*)
> >> until (funcall predicate local-input)
> >> do (format *query-io* repeat-prompt)
> >> finally (return local-input)))
> >
> > Why was (format *query-io* prompt) put inside of the LOOP?
> > Is it executed more than once?
>
> No; it is the argument of an initially clause, which specifies
> some evaluation to be done before the first iteration (in the "loop prologue"
> part of the expanded form).
>
> > Isn't it executed before
> > the looping starts? Why wasn't it put outside of the loop?
>
> For the same reason that i = 0 isn't put outside the loop in
>
> for (i = 0; i < n; i++) ...
>
> "outside the loop construct" isn't where "the looping starts". The looping, as
> it were, starts, roughly, when the first test is made which can determine
> whether any of the repeated parts of the loop will or will not execute.
>
> (For a simple while loop construct like (while cond body ...), this is indeed
> right inside the loop; no execution enclosed in the loop form is prior
> to the start of the looping.)
>
> > Putting it inside of the loop accomplishes nothing but
> > increasing the size of the code.
>
> It is not obvious that this would be the case, even if it were
> executed more than once. Unless you mean, "increases the size of the
> source code by the symbol 'initially'", rather than the object code.
>
> The answer to that is that Erik Naggum wasn't the type of coder who worried
> about minimizing token count in the source code.
>
> It is tidy to have everything in the loop, even if you have to pay
> for that with extra clause keywords to put it all there.

I wonder why WJ did not complain about the finally clause.

One mistake here is that the initially and finally clauses are indeed part of the loop form -- without them it don't work. The confusion is thinking that loop contains only iteration. But iteration tends to involve also initialization and finalization, so loop like any good ball of mud includes all the needed ingredients.

WJ's big mistake is taking the name of the construct literally, but tedious people tend that way.

-hk

William James

6/15/2016 8:03:00 AM

0

WJ wrote:

> Erik Naggum wrote:
>
> > > (defun filtered-input (predicate prompt)
> > > "Obtain input that passes the predicate"
> > > (labels ((local-input ()
> > > (format t prompt)
> > > (read)))
> > > (do ((j (local-input) (local-input)))
> > > ((funcall predicate j) j))))
> > :
> > > It bothers me that I have to repeat myself in my do loop in the
> > > definition of j.
> > > Is there another idiom in common usage in common LISP?
> >
> > well, I would do one of these:
> >
> > (loop initially (format t prompt)
> > for local-input = (read)
> > until (funcall predicate local-input)
> > finally (return local-input))
> >
> > (do () () ;or `loop'
> > (format t prompt)
> > (let ((local-input (read)))
> > (when (funcall predicate local-input)
> > (return local-input))))
>
> ....
>
> > as a matter of user interface design, I think it would make sense to
> > indicate that a value was rejected and to use another prompt for repeats:
> >
> > (defun filtered-input (predicate prompt repeat-prompt)
> > (loop initially (format *query-io* prompt)
> > for local-input = (read *query-io*)
> > until (funcall predicate local-input)
> > do (format *query-io* repeat-prompt)
> > finally (return local-input)))
>
> Why was (format *query-io* prompt) put inside of the LOOP?
> Is it executed more than once? Isn't it executed before
> the looping starts? Why wasn't it put outside of the loop?
> Putting it inside of the loop accomplishes nothing but
> increasing the size of the code.
>
> Worshippers of CL (COBOL-Like) and LOOP are justly
> proud of their unmatched mindlessness.
>
>
> Gauche Scheme:
>
> (define (filtered-input predicate prompt repeat-prompt)
> (display prompt) (flush)
> (generator-find
> (lambda (local-input)
> (or (predicate local-input)
> (begin (display repeat-prompt) (flush) #f)))
> read))

OCaml:

let filtered_input test prompt repeat_prompt =
print_string prompt ;
let rec loop () =
let s = read_line () in
if test s then s else (print_string repeat_prompt; loop ())
in loop () ;;

# filtered_input (fun s->String.length s > 2) ":" "no:";;
:hi
no:hello
- : string = "hello"

--
This is war, and our greatest enemy is the enemy within: the submissive,
apologetic, guilt-ridden, self-hating drone. The moment we manage to destroy
the enemy within, destroying the rest of our enemies will be a walk in the
park. http://www.kolumbus.fi/aquilon/londonsp...