ways to allow a procedure to see its own tags
Peter McGoron 15 Apr 2025 01:29 UTC
Hello,
Is there a good way for a procedure to see its own tags? I could just
pass the procedure as an argument like
(proc proc args ...)
or wrap that in a macro, but it seems inelegant and error prone.
I can't use letrec like
(letrec ((proc (lambda args etc ...)) proc)
because if the procedure is tagged by a protocol, the constructor
returns a new procedure, which `proc` does not point to.
I wrote in my Chicken implementation[1] a macro that makes a closure
that has an identifier `this` bound to itself. It uses internal
procedures in the SRFI-259 implementation to copy all the tags to a new
procedure that encapsulates the old procedure when a new tag is added to
it. When a constructor is applied to the procedure, the procedure that
comes out when called will have `this` bound to the new procedure during
its execution.
Here's an example, where the macro that creates this sort of procedure
is called `lambda/this`:
(define-procedure-tag tag-foo tag-foo? get-tag-foo)
(define f (lambda/this this (x)
(if (tag-foo? this)
(+ x (get-tag-foo this))
x)))
(f 10) ; => 10
(define g (tag-foo 10 f))
(g 10) ; => 20
(f 10) ; => 10
Should something like this be included into the SRFI? Or is there a
portable way to do this efficiently with just `define-procedure-tag`?
[1]: https://wiki.call-cc.org/eggref/5/srfi-259
-- Peter McGoron