bug-guile
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: shift and reset, plus "while"


From: Wolfgang J Moeller
Subject: Re: shift and reset, plus "while"
Date: Mon, 4 Apr 2011 15:05:20 +0200 (CEST)

Hi,

co-routine linkage problem solved!

All it takes, is taking care that each [full] continuation
seen by one co-routine are equivalent, so it doesn't matter
which one gets saved and restored. No continuation-barrier
or dynamic-wind required!

While not obvious at first glance, doing so is easy enough -
at least by "imperative" programming throughout. I believe that
now my co-routine linkage works for prompt-based reset/shift
just the same as for call/cc-based reset/shift.

===

My pet peeve: (while).

First a compiler bug (in V2.0.0),
plus mis-behaviour after a stack overflow:

| address@hidden guile2 --no-auto-compile
| using readline (~/.guile) ...
| GNU Guile 2.0.0
| Copyright (C) 1995-2011 Free Software Foundation, Inc.
|
| Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
| This program is free software, and you are welcome to redistribute it
| under certain conditions; type `,show c' for details.
|
| Enter `,help' for help.
| 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" ())'.
|
| Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
| scheme@(guile-user) [1]>
| scheme@(guile-user) [1]> (display (while #f 1))
| Segmentation fault
| address@hidden

You can
        (define (f) (display (while #f 1)))
which also gets the code wrong, and ,disassemble ...

Btw,
        (define (f) (while #f 1))
        (display (f))
does work (--> #<unspecified>), as does
        (while #f 1)
at top level.

===

Second, this is how I'd like to "improve" (while)
as currently provided by ice-9/boot.scm :

(a) to always have a well-defined result
(b) to allow for (break arg ...)
(c) to only take a single (call-with-prompt)
(d) to correct a buglet that currently transforms the non-operator `continue'
    into a function of arbitrarily many (as opposed to zero) arguments.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; {while} with `continue' and `break'.
;;
;;; wjm: Will the inliner eventually remove the prompt at compile-time
;;;      if it finds that neither `continue' nor `break' are used?
;;; NB. The optimization, as announced in ice-9/boot.scm, doesn't work out yet.
;;
;; returns:
;;      #f              on normal termination   - sort-of compatible to GUILE
;;                                                which returns #<unspecified>
;;      #t              on (break)              - compatible
;;      (values v ...)  on (break v ...)        - compatible extension
;;
(define-syntax while
  (lambda (x)
    (syntax-case x ()
      ((while cond . body)
       #`(let ((tag (make-prompt-tag "while")))
           (let lp ()
             (call-with-prompt
              tag
              ;;
              (lambda ()
                ;;
                (define-syntax #,(datum->syntax #'while 'break)
                  (lambda (x)
                    (syntax-case x ()
                      ((_ . vals)
                       #'(abort-to-prompt tag #f . vals))
                      (_
                       #'(lambda vals
                           (apply abort-to-prompt tag #f vals))))))
                ;;
                (define-syntax #,(datum->syntax #'while 'continue)
                  (lambda (x)
                    (syntax-case x ()
                      ((_)
                       #'(abort-to-prompt tag #t))
                      ((_ . args)
                       (syntax-violation 'continue "too many arguments" x))
                      (_
                       #'(lambda ()
                           (abort-to-prompt tag #t))))))
                ;;
                (do ()
                    ((not cond) #f)
                  . body))
              ;;
              (lambda (k cont? . vals)
                (if cont?
                    (lp)
                    (or (null? vals)
                        (apply values vals)))))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

NB. "body ..." (etc.) replaced by ". body" so my LISP-based Scheme can read it 
too.

As of V2.0.0, the modified macro runs into the same problems
as the built-in (while) shown above.

Feel free to select the modifications you like!

===

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?


Schöne Grüße,

Dr. Wolfgang J. Möller                   <address@hidden>
Arbeitsgruppe IT-Infrastruktur         Tel. +49 551 201-1516
----------------------------------------------------- G W D G ----
Gesellschaft für wissenschaftliche Datenverarbeitung mbH Göttingen
Am Fassberg 11, 37077 Göttingen
E-Mail: address@hidden                   Tel.:   +49 (0)551 201-1510
URL:    http://www.gwdg.de             Fax:    +49 (0)551 201-2150
Geschäftsführer:            Prof. Dr. Oswald Haan, Dr. Paul Suren
Aufsichtsratsvorsitzender:  Prof. Dr. Christian Griesinger
Sitz der Gesellschaft:      Göttingen
Registergericht:            Göttingen  Handelsregister-Nr. B 598
------------------------------------------------------------------

reply via email to

[Prev in Thread] Current Thread [Next in Thread]