guile-devel
[Top][All Lists]
Advanced

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

Re: Non-stack-copying call-with-current-continuation?


From: Mark H Weaver
Subject: Re: Non-stack-copying call-with-current-continuation?
Date: Sun, 04 Mar 2012 19:35:33 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux)

David Kastrup <address@hidden> writes:

> Mark H Weaver <address@hidden> writes:
>
>> David Kastrup <address@hidden> writes:
>>
>>> The symbol name is not garbage collected.  That is the difference
>>> between gensym and make-symbol.
>>
>> Integers are plentiful and cheap.
>
> We are not talking about an integer generated statically here.  We are
> talking about integers getting burned through every time a control
> structure is being used.  Not at compilation time, but at runtime.  And
> with today's computers, executing a loop often enough that the integers
> don't fit into a single Scheme cell anymore and stop being cheap is not
> really an extraordinary event.

Indeed, this is a good point, and another reason why we need the
efficient gensym hack.

>> Also, in Guile 2, prompt tags need not be symbols.  Anything that can
>> be compared with 'eq?' will work.
>
> I suppose there is no compelling technical reason why this could not be
> made to also work with catch/throw, right?  Being able to use something
> like (list #f) instead of gensym would seriously reduce the cost, both
> felt as well as actual.

Indeed, I see no reason why catch/throw shouldn't accept non-symbol
tags.  Looking through the code of Guile 1.8, I see nothing that depends
upon the tag being a symbol.  Unfortunately, catch/throw have long been
documented as requiring a symbol, and raise an error if given a
non-symbol, at least as far back as Guile 1.4.

However, catch/throw _will_ accept uninterned symbols created with
'make-symbol'.

Here's a faster implementation of call/ec that uses (list 'call/ec) to
create prompt tags on Guile 2, and (make-symbol "call/ec") on earlier
versions of Guile:

  (cond-expand
   (guile-2 (define (call-with-escape-continuation proc)
              (let ((tag (list 'call/ec)))
                (call-with-prompt
                 tag
                 (lambda () (proc (lambda xs (abort-to-prompt tag xs))))
                 (lambda (k xs) (apply values xs))))))
  
   (guile (define (call-with-escape-continuation proc)
            (let ((key (make-symbol "call/ec")))
              (catch key
                (lambda () (proc (lambda xs (throw key xs))))
                (lambda (key xs) (apply values xs)))))))
  
  (define call/ec call-with-escape-continuation)

     Regards,
       Mark



reply via email to

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