unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Re: shift and reset, plus "while"
       [not found] <alpine.LNX.2.00.1104041402090.26447@gwdw03.gwdg.de>
@ 2011-04-13  9:47 ` Andy Wingo
  2011-04-13 14:56   ` [shift and reset, plus] "while" Wolfgang J Moeller
  0 siblings, 1 reply; 5+ messages in thread
From: Andy Wingo @ 2011-04-13  9:47 UTC (permalink / raw)
  To: Wolfgang J Moeller; +Cc: bug-guile, guile-devel

Hi Wolfgang,

Another in a series of asynchronous replies :)  Copying guile-devel for
comments on the extensions to `while'.

On Mon 04 Apr 2011 15:05, Wolfgang J Moeller <wjm@heenes.com> writes:

> | GNU Guile 2.0.0
> | scheme@(guile-user)> (display (while #f 1))
> | <unnamed port>:0:0: In procedure #<procedure 887aa60 at <current input>:1:0 ()>:
> | <unnamed port>:0:0: Throw to key `vm-error' with args `(vm-run "VM: Stack overflow" ())'.

This is the same compiler bug as before, which is fixed in stable-2.0.
We'll push out a release Real Soon Now (TM).

> I'd like to "improve" (while) as currently provided by ice-9/boot.scm
>
> (a) to always have a well-defined result

This is a good idea; it allows `while' to be an expression, not just a
statement.

> (b) to allow for (break arg ...)

Also a good idea.

Tricky, though; your comments indicate that you would want (break) to
return #t, instead of zero values.

> (c) to only take a single (call-with-prompt)

Why?  It's true that the optimizer doesn't live up to its name yet, but
it should be trivial to elide one or the other if the prompt tag is only
referenced by the <prompt> form.

> (d) to correct a buglet that currently transforms the non-operator `continue'
>     into a function of arbitrarily many (as opposed to zero)
>     arguments.

I have not seen this bug.  Do you have code that can reproduce it with
stable-2.0 ?

> Just a hint: (GPLed) CLISP's compiler is written in LISP and in my
> experience perfectly succeeds at removing all redundant
> branches. Maybe something to look at?

No doubt, it would be instructive!

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [shift and reset, plus] "while"
  2011-04-13  9:47 ` shift and reset, plus "while" Andy Wingo
@ 2011-04-13 14:56   ` Wolfgang J Moeller
  2011-04-13 15:41     ` Andy Wingo
  0 siblings, 1 reply; 5+ messages in thread
From: Wolfgang J Moeller @ 2011-04-13 14:56 UTC (permalink / raw)
  To: Andy Wingo; +Cc: bug-guile, guile-devel

On Wed, 13 Apr 2011, Andy Wingo wrote:

>[...]
> > I'd like to "improve" (while) as currently provided by ice-9/boot.scm
> >
> > (a) to always have a well-defined result
>
> This is a good idea; it allows `while' to be an expression, not just a
> statement.
>
> > (b) to allow for (break arg ...)
>
> Also a good idea.
>
> Tricky, though; your comments indicate that you would want (break) to
> return #t, instead of zero values.

Does anyone like to _test_ for zero values? Not me.
As regards the REPL, you still can (break (if #f #f)).

Alternative: return zero values on "normal termination",
instead of #<unspecified>, so the REPL keeps quiet then,
as it did before. Not as handy, but at least well-defined.

I don't remember if GUILE V1.6 had the return values of #f and #t,
or if they were my own invention ... IIRC it did have (break arg)
with a single argument. Anyway, #t is compatible with V2.0.0 .

Not exactly tricky - see my code's prompt handler.

> > (c) to only take a single (call-with-prompt)
>
> Why?  It's true that the optimizer doesn't live up to its name yet, but
> it should be trivial to elide one or the other if the prompt tag is only
> referenced by the <prompt> form.

Just for simplification of the macro - it's plain overkill to create two prompts.
Nothing to do with the optimizer per se; my note only relates to the fact that
the (promised) optimization ought to work just as well with the single prompt.

> > (d) to correct a buglet that currently transforms the non-operator `continue'
> >     into a function of arbitrarily many (as opposed to zero)
> >     arguments.
>
> I have not seen this bug.  Do you have code that can reproduce it with
> stable-2.0 ?

No code - it's a buglet w/o much consequence - from ice-9/boot-9.scm :

[...]
;;; {While}
[...]
(define-syntax while
  [...]
  (define-syntax #,(datum->syntax #'while 'continue)
    (lambda (x)
      (syntax-case x ()
	((_)
	 #'(abort-to-prompt continue-tag))
	((_ . args)		; <<<<< wjm: no argumenta allowed - OK
	 (syntax-violation 'continue "too many arguments" x))
	(_
	 #'(lambda args		; <<<<< wjm: arguments allowed - WHY??
	     (apply abort-to-prompt continue-tag args))))))
  [...])

Stand-alone fix:

	((_ . args)		; no arguments allowed
	 (syntax-violation 'continue "too many arguments" x))
	(_
	 #'(lambda ()		; also, zero arguments
	     (abort-to-prompt continue-tag)))))


Best regards,

Wolfgang J. Moeller, Tel. +49 551 47361, wjm<AT>heenes.com
37085 Goettingen, Germany | Disclaimer: No claim intended!
http://www.wjmoeller.de/ -+-------- http://www.heenes.com/



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [shift and reset, plus] "while"
  2011-04-13 14:56   ` [shift and reset, plus] "while" Wolfgang J Moeller
@ 2011-04-13 15:41     ` Andy Wingo
  2011-04-13 17:31       ` Wolfgang J Moeller
  0 siblings, 1 reply; 5+ messages in thread
From: Andy Wingo @ 2011-04-13 15:41 UTC (permalink / raw)
  To: Wolfgang J Moeller; +Cc: bug-guile, guile-devel

On Wed 13 Apr 2011 16:56, Wolfgang J Moeller <wjm@heenes.com> writes:

> On Wed, 13 Apr 2011, Andy Wingo wrote:
>
>>[...]
>> > I'd like to "improve" (while) as currently provided by ice-9/boot.scm
>> >
>> > (a) to always have a well-defined result
>>
>> This is a good idea; it allows `while' to be an expression, not just a
>> statement.
>>
>> > (b) to allow for (break arg ...)
>>
>> Also a good idea.
>>
>> Tricky, though; your comments indicate that you would want (break) to
>> return #t, instead of zero values.
>
> Does anyone like to _test_ for zero values? Not me.
> As regards the REPL, you still can (break (if #f #f)).
>
> Alternative: return zero values on "normal termination",
> instead of #<unspecified>, so the REPL keeps quiet then,
> as it did before. Not as handy, but at least well-defined.
>
> I don't remember if GUILE V1.6 had the return values of #f and #t,
> or if they were my own invention ... IIRC it did have (break arg)
> with a single argument. Anyway, #t is compatible with V2.0.0 .

From Guile 1.6:

    (defmacro while (cond . body)
      `(letrec ((continue (lambda () (or (not ,cond) (begin (begin ,@ body) (continue)))))
                (break (lambda val (apply throw 'break val))))
         (catch 'break
    	    (lambda () (continue))
    	    (lambda v (cadr v)))))

It did indeed happen to return #t on a normal termination, and have
(break ARG).  It has lots of other bugs though.  I would prefer (break)
to return zero values, and (while #f 1) as well, but that is
incompatible with 2.0.  Bummer.

> Not exactly tricky - see my code's prompt handler.

I didn't mean in terms of code; I meant in terms of documentation,
interface, expectations, etc...

>> > (d) to correct a buglet that currently transforms the non-operator `continue'
>> >     into a function of arbitrarily many (as opposed to zero)
>> >     arguments.

I hadn't seen this one because Mark Weaver fixed it a few weeks ago, in
ddf134cfec0d82ea9f39ddd69948c08feecb9576.

Cheers,

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [shift and reset, plus] "while"
  2011-04-13 15:41     ` Andy Wingo
@ 2011-04-13 17:31       ` Wolfgang J Moeller
  2011-04-28 12:15         ` Andy Wingo
  0 siblings, 1 reply; 5+ messages in thread
From: Wolfgang J Moeller @ 2011-04-13 17:31 UTC (permalink / raw)
  To: Andy Wingo; +Cc: bug-guile, guile-devel

On Wed, 13 Apr 2011, Andy Wingo wrote:

>[...]
> >From Guile 1.6:
>[...]
> It did indeed happen to return #t on a normal termination, and have
> (break ARG).  It has lots of other bugs though.  I would prefer (break)
> to return zero values, and (while #f 1) as well, but that is
> incompatible with 2.0.  Bummer.

OK, that explains why I have an old & lengthy program that does use
(break arg), and why I had to keep my macro compatible.

Last resort: Once we do allow for argument(s) to (break),

   (while #t ... (break x) ... (break y) ...)

allows for full functionality, plus returning all well-defined results,
without necessarily requiring well-defined (or even different) results
from (break) and (while #f).

Only that this construct might better be called "loop/return" ...

Given the situation at V2.0.0, with the only results being
#<unspecified> and #t (plus compiler error!), and [at least]
V1.8.5 returning nothing but #<unspecified>, I find it hard
to believe that (break) ==> #t had found an application yet.

Or maybe someone can come up with a pretty formulation
of a newly invented "do-until/break/continue" combo ...

> > Not exactly tricky - see my code's prompt handler.
>
> I didn't mean in terms of code; I meant in terms of documentation,
> interface, expectations, etc...

Indeed. I'd like to say thanks to the authors of the new/improved GUILE manual.
Real good. E.g. finally, a description of "syntax-case" that I'd understand
(as opposed to R6RS ;-)!

Best regards,

Wolfgang J. Moeller, Tel. +49 551 47361, wjm<AT>heenes.com
37085 Goettingen, Germany | Disclaimer: No claim intended!
http://www.wjmoeller.de/ -+-------- http://www.heenes.com/



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [shift and reset, plus] "while"
  2011-04-13 17:31       ` Wolfgang J Moeller
@ 2011-04-28 12:15         ` Andy Wingo
  0 siblings, 0 replies; 5+ messages in thread
From: Andy Wingo @ 2011-04-28 12:15 UTC (permalink / raw)
  To: Wolfgang J Moeller; +Cc: bug-guile, guile-devel

On Wed 13 Apr 2011 19:31, Wolfgang J Moeller <wjm@heenes.com> writes:

> Last resort: Once we do allow for argument(s) to (break),
>
>    (while #t ... (break x) ... (break y) ...)

If I understand you right, this is more like a coroutine, which could
use an orthogonal form:

(define-syntax with-yield
  (lambda (x)
    (syntax-case x ()
      ((_ yield exp exp* ...) (identifier? #'yield)
       #'(let ((tag (make-prompt-tag)))
           (define (handler k . args)
             (define (resume . args)
               (call-with-prompt tag
                 (lambda () (apply k args))
                 handler))
             (apply values resume args))

           (call-with-prompt
            tag
            (lambda ()
              (let-syntax ((yield (syntax-rules ()
                                    ((_ arg (... ...))
                                     (abort-to-prompt tag arg (... ...))))))
                exp exp* ...))
           handler))))))

Then you can

  (with-yield yield
    (while #t ... (yield) ...))

Regards,

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-04-28 12:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <alpine.LNX.2.00.1104041402090.26447@gwdw03.gwdg.de>
2011-04-13  9:47 ` shift and reset, plus "while" Andy Wingo
2011-04-13 14:56   ` [shift and reset, plus] "while" Wolfgang J Moeller
2011-04-13 15:41     ` Andy Wingo
2011-04-13 17:31       ` Wolfgang J Moeller
2011-04-28 12:15         ` Andy Wingo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).