Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.lisp > #32932

Re: symbol-macros -vs- symbol setf-expander

From Kaz Kylheku <847-115-0292@kylheku.com>
Newsgroups comp.lang.lisp
Subject Re: symbol-macros -vs- symbol setf-expander
Date 2019-05-21 21:25 +0000
Organization Aioe.org NNTP Server
Message-ID <20190521125844.749@kylheku.com> (permalink)
References <jwv5zq3eh4i.fsf-monnier+comp.lang.lisp@gnu.org>

Show all headers | View raw


On 2019-05-21, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> While discussing some extension to Elisp's `gv`, someone pointed out
> that symbol-macros basically allow you to define a symbol as an
> arbitrary "place", i.e. a kind of "place alias".
>
> Yet, it's subtly different since
>
>     (symbol-macrolet ((x (nth 5 (get-list)))) ...)
>     
> will re-execute (get-list) (and `nthcdr 5`) everytime `x` is used
> without offering any easy way to take advantage of the setf-expander
> infrastructure's ability to do those computations only once.
>
> Does anyone here know of work related to this, e.g. discussions about
> the detailed semantics of symbol-macrolet?

We have probably discussed this before, but in TXR Lisp I provide
something called placelet.

Placelet lexically binds symbols nicknames to places (similarly to
symbol macros), but with once-only semantics.

Ten second demo:

1> (expand '(placelet ((x (nth 5 (get-list))))
              (list x x (inc x))))
(let ((#:g0011 (nthcdr 5 (get-list))))
  (list (car #:g0011)
        (car #:g0011)
        (sys:rplaca #:g0011 (succ (car #:g0011)))))

Doc: http://nongnu.org/txr/txr-manpage.html#N-0393C970

Implementation: http://www.kylheku.com/cgit/txr/tree/share/txr/stdlib/place.tl

The bulk of the logic is in a macro called sys:placelet-1.

symbol-macrolet (called symacrolet) plays a key role, as do multiple
occurrences of macrolet; placelet isn't symacrolet, but its implementation
depends on it.

How the implementation works is that during expansion, placelet will
dynamically insert place definitions into the global hash table,
and then remove them (via unwind-protect).

The symbol in question, like in this case x, is then macro-replaced
with references to the temporary place.

The details are little tricky. The definitions use gensyms, so for instance
a place resembling (#:g0025) is defined whose "getter" might be
a form like (#:g0009) and whose setter is (#:g0010 <new-value>).
This #:g0025 is held in the tmp-place variable in sys:placelet-1
implementation.

The code is generated to instantiate the original (nth 5 ...) place.
The #:g0011 gensym is bound to (nthcdr 5 (get-list)). Together with this,
local macros are provided using gensym-ed names, so that the macrolet (#:g0009)
expands to the access (car #:g0011), and the macrolet form (#:g0010 whatever)
expands to (sys:rplaca #:g0011 whatever). These are the tmp-getter and
tmp-setter gensyms in sys:placelet-1.

The symbol x is then forcibly replaced with (#:g0025) throughout the code body
(full expand pass). At that stage the code fragments then looks like:

  (let ((#:g0011 (nthcdr 5 (get-list))))
    (macrolet ((#:g0009 () (car #:g0011)))
               (#:g0010 (val) (sys:rplaca #:g0011 val)))

      ;; tenative inner fragment: not finished yet:
      (list (#:g0025) (#:g0025) (sys:rplaca #:g0011 (succ (car #:g0011)))))

We can see that the simple accesses to x are replaced by just (#:g0025),
the form denoting the temporary place.  But where this is (#:g0025) is actually
used as a place, in the (inc ...) form, it is processed all the way to
(sys:rplaca #:g0011 ...) thanks to the workings of the temporary registration
of the (#:g0025) alias place.

Why (#:g0025) didn't get expanded into anything is that we have not defined
such a function or macro; we have (dynamically/locally) defined the place
(#:g0025) only, but for a fictitious form (#:g0025) that has no binding.

So now we are introducing that binding: we map (#:0025) to the access macrolet
(#:g0009):

  (macrolet ((#:g0025 (#:g0009))) ...)

Ending up with:

  (let ((#:g0011 (nthcdr 5 (get-list))))
    (macrolet ((#:g0009 () (car #:g0011)))  ;; <---- #:g0009 is here!
               (#:g0010 (val) (sys:rplaca #:g0011 val)))
      (macrolet ((#:g0025 (#:g0009))) ;; <--- referenced from here!
        (list (#:g0025) (#:g0025) (sys:rplaca #:g0011 (succ (car #:g0011))))))

This inner macrolet shakes out the (#:g0025) forms, replacing them with
(#:g0009) which immediately goes to the (car #:g0011) access form,
thanks to the outer macrolet.

-- 
TXR Programming Lanuage: http://nongnu.org/txr
Music DIY Mailing List:  http://www.kylheku.com/diy
ADA MP-1 Mailing List:   http://www.kylheku.com/mp1

Back to comp.lang.lisp | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

symbol-macros -vs- symbol setf-expander Stefan Monnier <monnier@iro.umontreal.ca> - 2019-05-21 15:46 -0400
  Re: symbol-macros -vs- symbol setf-expander Kaz Kylheku <847-115-0292@kylheku.com> - 2019-05-21 21:25 +0000
    Re: symbol-macros -vs- symbol setf-expander Kaz Kylheku <847-115-0292@kylheku.com> - 2019-05-22 20:07 +0000
      Re: symbol-macros -vs- symbol setf-expander Stefan Monnier <monnier@iro.umontreal.ca> - 2019-05-30 15:40 -0400
        Re: symbol-macros -vs- symbol setf-expander Kaz Kylheku <847-115-0292@kylheku.com> - 2019-05-31 04:51 +0000
          Re: symbol-macros -vs- symbol setf-expander "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-05-31 16:38 +0200
            Re: symbol-macros -vs- symbol setf-expander Kaz Kylheku <847-115-0292@kylheku.com> - 2019-05-31 18:42 +0000
              Re: symbol-macros -vs- symbol setf-expander "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-05-31 21:24 +0200
                Re: symbol-macros -vs- symbol setf-expander Kaz Kylheku <847-115-0292@kylheku.com> - 2019-06-01 02:34 +0000
              Re: symbol-macros -vs- symbol setf-expander Stefan Monnier <monnier@iro.umontreal.ca> - 2019-05-31 18:14 -0400
                Re: symbol-macros -vs- symbol setf-expander Kaz Kylheku <847-115-0292@kylheku.com> - 2019-06-01 02:51 +0000
                Re: symbol-macros -vs- symbol setf-expander Stefan Monnier <monnier@iro.umontreal.ca> - 2019-06-02 12:16 -0400
                Re: symbol-macros -vs- symbol setf-expander Kaz Kylheku <847-115-0292@kylheku.com> - 2019-06-03 01:13 +0000
        Re: symbol-macros -vs- symbol setf-expander Stefan Monnier <monnier@iro.umontreal.ca> - 2019-05-31 18:04 -0400
  Re: symbol-macros -vs- symbol setf-expander "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-05-22 22:00 +0200
    Re: symbol-macros -vs- symbol setf-expander a.daniel.eliason@gmail.com - 2019-05-23 08:10 -0700
      Re: symbol-macros -vs- symbol setf-expander Spiros Bousbouras <spibou@gmail.com> - 2019-05-23 15:22 +0000
        Re: symbol-macros -vs- symbol setf-expander Dimitri Fontaine <dim@tapoueh.org> - 2019-05-23 18:02 +0200
          Re: symbol-macros -vs- symbol setf-expander Spiros Bousbouras <spibou@gmail.com> - 2019-05-23 16:51 +0000
        Re: symbol-macros -vs- symbol setf-expander Kaz Kylheku <847-115-0292@kylheku.com> - 2019-05-23 17:05 +0000
          Re: symbol-macros -vs- symbol setf-expander "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-05-23 19:26 +0200
  Re: symbol-macros -vs- symbol setf-expander smh <shaflich@gmail.com> - 2019-05-22 18:47 -0700

csiph-web