Oh yes, you're right. I'm sorry I missed it. I believe you can do it hygienically though. With prompts, you can use (make-prompt-tag) to generate a new, unique tag. With catch and throw, you could use (gensym) to do the same thing. You first example would become something like
(define-public (find-child music predicate) "Find the first node in @var{music} that satisfies @var{predicate}." (let ((music-found-tag (gensym))) (catch music-found-tag (lambda () (fold-some-music predicate (lambda (music . _) (throw music-found-tag music)) #f music)) (lambda (key music) music))) Does that work? Noah On Thu, Mar 1, 2012 at 7:42 PM, David Kastrup <d...@gnu.org> wrote: > Noah Lavine <noah.b.lav...@gmail.com> writes: > >> On Thu, Mar 1, 2012 at 7:00 PM, David Kastrup <d...@gnu.org> wrote: >>> >>> Hi, >>> >>> I am just meddling around with coding and have come up with the >>> following: >>> >>> (define-public (find-child music predicate) >>> "Find the first node in @var{music} that satisfies @var{predicate}." >>> (catch 'music-found >>> (lambda () >>> (fold-some-music predicate >>> (lambda (music . _) (throw 'music-found music)) >>> #f music)) >>> (lambda (key music) music))) >>> >>> Now the problem with that is that it is unhygienic. If fold-some-music >>> were to use music-found signals, or if the predicate did, things would >>> be awkward. One would need to work with a uniquely generated symbol. >>> It turns out that the above can be expressed much clearer and cleaner as >>> >>> (define-public (find-child music predicate) >>> "Find the first node in @var{music} that satisfies @var{predicate}." >>> (call-with-current-continuation >>> (lambda (music-found) >>> (fold-some-music predicate >>> (lambda (music . _) (music-found music)) >>> #f music)))) >>> >>> at least if I did not make some thinko here. It is basically the same >>> code and stack-upwards-only, but hygienic. Nothing can call the >>> continuation but what is inside. Well, of course fold-some-music could >>> save the closure calling music-found for later. But it doesn't. >>> >>> Is there a way to get a call-with-current-continuation that does not >>> create a stack copy? It is fine if it fails with an exception if one >>> still tries calling the continuation after it has already returned. >> >> If I understand correctly, you only need to call the continuation >> once. Is that right? >> >> In that case, I think you could use either catch and throw or prompts. > > Neither of which are hygienic and also less straightforward. It is not > like I did not start my posting by giving the catch/throw-based example > and saying what I disliked about it. > > -- > David Kastrup > >