Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

You will always get the greatest recognition for the job you least like.


comp / comp.lang.scheme / Re: macro flow from inside to outside

SubjectAuthor
o Re: macro flow from inside to outsideB. Pym

1
Subject: Re: macro flow from inside to outside
From: B. Pym
Newsgroups: comp.lang.lisp, comp.lang.scheme
Organization: A noiseless patient Spider
Date: Wed, 11 Sep 2024 05:04 UTC
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Nobody447095@here-nor-there.org (B. Pym)
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: Re: macro flow from inside to outside
Date: Wed, 11 Sep 2024 05:04:55 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 78
Message-ID: <vbr8dj$3emd5$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Injection-Date: Wed, 11 Sep 2024 07:04:55 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="3be87affaab0b87468eb137bb3ffc6ef";
logging-data="3627429"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/KcmUa8wV2f+x/isUy/XE4"
User-Agent: XanaNews/1.18.1.6
Cancel-Lock: sha1:8VSFv/3QYSwIHFguEQBOlauIqoQ=
View all headers

Peter Seibel wrote:

> that didn't just throw away those valuse. Here' a version that uses
> lexical variables, as requested. However it suffers from only allowing
> a finite number of named bags. There may be some clever way to work
> around that without walking the code. Or you could just live with it,
> the same way we live with other limits such as the number of arguments
> we can pass to a function.
>
> (defmacro bag (&body body)
> (let ((bag (gensym))
> (namedbags (loop repeat 10 collect (gensym))))
> `(let ((,bag ())
> ,@(loop for bag in namedbags collect `(,bag ())))
> (flet ((find-bag (name)
> (cond
> (name
> (loop for bag in ',namedbags
> for bagname = (get bag 'bag-name)
> when (eql name bagname) return bag
> when (not bagname) do
> (setf (get bag 'bag-name) name) and
> return bag
> finally (error "Out of bags")))
> (t ',bag))))
> (macrolet ((containing (item &optional name)
> `(push ,item ,(find-bag name)))
> (the-bag (name)
> (find-bag name)))
> ,@body)
> ,bag))))
>
> This lets you write stuff like:
>
> CL-USER> (bag
> (dotimes (i 10)
> (if (evenp i)
> (containing i evens)
> (containing i odds)))
> (containing (the-bag evens))
> (containing (the-bag odds)))
> ((9 7 5 3 1) (8 6 4 2 0))

Gauche Scheme

(let@ ('() odds evens)
(dotimes (i 10)
(if (odd? i) (push! odds i) (push! evens i)))
(list evens odds))

((8 6 4 2 0) (9 7 5 3 1))

Given:

(define-syntax let@-aux
(syntax-rules ()
[(let@-aux ('() var ...) (pairs ...) stuff)
(let@-aux () (pairs ... (var '()) ...) stuff)]
[(let@-aux (var val more ...) (pairs ...) stuff)
(let@-aux (more ...) (pairs ... (var val)) stuff)]
[(let@-aux (var) pairs stuff)
(let@-aux (var '()) pairs stuff)]
[(let@-aux () ((var val) ...) (stuff ...))
(let* ((var val) ...) stuff ...)]))
(define-syntax let@
(syntax-rules ()
[(let@ things stuff ...)
(let@-aux things () (stuff ...))]))

Another way.

(lope
collectors (evens odds)
upto i 0 9
((if (odd? i) odds evens) i))

'(0 2 4 6 8)
'(1 3 5 7 9)

1

rocksolid light 0.9.8
clearnet tor