ways to allow a procedure to see its own tags Peter McGoron (15 Apr 2025 01:33 UTC)
Re: ways to allow a procedure to see its own tags Daphne Preston-Kendal (15 Apr 2025 07:58 UTC)

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