• sharing &rest macro lambda lists - conformance question

    From Madhu@21:1/5 to All on Sun Mar 20 14:33:46 2022
    consider a hypothetical macro BARF which destructively modifies its
    &rest list - it rotates the first two arguments in place:

    #+begin_src lisp
    (defmacro barf (&rest list)
    "rotates the first two arguments to produce a list"
    (let ((a (car list))
    (b (cadr list)))
    (setf (car list) b (cadr list) a)
    `(list ,@list)))

    (macroexpand-1 '(barf 1 2)) ; => (list 2 1)

    (defmacro cowf ()
    `(let ((a 1) (b 2) (c 3) (d 4))
    (barf a b c d)))

    (macroexpand-1 '(cowf)) ; =>
    ;; => (LET ((A 1) (B 2) (C 3) (D 4)) (BARF A B C D)), T

    (cowf) ;; => (2 1 3 4)

    (macroexpand-1 '(cowf)) =>
    ;; (LET ((A 1) (B 2) (C 3) (D 4))
    ;; (BARF B A C D))

    ;; i.e. executing COWF changes the macrofunction to toggle between
    ;; calling (BARF A B C D) and (BARF B A C D)
    #+end_src

    Clearly BARF should be written functionally so it doesn't mutate the
    &rest lambda list.

    But is this issue (of &rest lambda lists) written up anywhere? Has it
    been discussed on cll before? Doesn't this behaviour of the compiler on DEFMACRO have to be specified? Are there any problems in required it to
    cons up a new &rest list for each expansion?

    Only allegro seems to implement the last behaviour, which I think
    is the desired behaviour

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Spiros Bousbouras@21:1/5 to Madhu on Sun Mar 20 11:24:40 2022
    On Sun, 20 Mar 2022 14:33:46 +0530
    Madhu <enometh@meer.net> wrote:

    consider a hypothetical macro BARF which destructively modifies its
    &rest list - it rotates the first two arguments in place:

    #+begin_src lisp
    (defmacro barf (&rest list)
    "rotates the first two arguments to produce a list"
    (let ((a (car list))
    (b (cadr list)))
    (setf (car list) b (cadr list) a)
    `(list ,@list)))

    (macroexpand-1 '(barf 1 2)) ; => (list 2 1)

    (defmacro cowf ()
    `(let ((a 1) (b 2) (c 3) (d 4))
    (barf a b c d)))

    (macroexpand-1 '(cowf)) ; =>
    ;; => (LET ((A 1) (B 2) (C 3) (D 4)) (BARF A B C D)), T

    (cowf) ;; => (2 1 3 4)

    (macroexpand-1 '(cowf)) =>
    ;; (LET ((A 1) (B 2) (C 3) (D 4))
    ;; (BARF B A C D))

    ;; i.e. executing COWF changes the macrofunction to toggle between
    ;; calling (BARF A B C D) and (BARF B A C D)
    #+end_src

    Clearly BARF should be written functionally so it doesn't mutate the
    &rest lambda list.

    But is this issue (of &rest lambda lists) written up anywhere?

    3.1.2.1.2.2 Macro Forms
    The consequences are undefined if a macro function destructively
    modifies any part of its form argument.

    Has it
    been discussed on cll before? Doesn't this behaviour of the compiler on DEFMACRO have to be specified?

    I don't think that CLHS tends to specify such esoteric implementation details and for good reason. If you want a fresh &rest list you can trivially
    create one so why should the CLHS specify anything ?

    Are there any problems in required it to
    cons up a new &rest list for each expansion?

    It's not a good idea for a standard to specify implementation details.

    Only allegro seems to implement the last behaviour, which I think
    is the desired behaviour

    --
    CALAMARI WRESTLER is basically a "boxing movie", and follows most of the conventions of the genre... with the exception of species.
    https://www.imdb.com/review/rw1419366/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Madhu@21:1/5 to All on Sun Mar 20 17:26:51 2022
    * Spiros Bousbouras <tVe7JBPzk+ZwEkDjT@bongo-ra.co> :
    Wrote on Sun, 20 Mar 2022 11:24:40 -0000 (UTC):
    Clearly BARF should be written functionally so it doesn't mutate the
    &rest lambda list.
    But is this issue (of &rest lambda lists) written up anywhere?

    3.1.2.1.2.2 Macro Forms
    The consequences are undefined if a macro function destructively
    modifies any part of its form argument.

    Thanks. I knew I was missing a spot.

    Has it been discussed on cll before? Doesn't this behaviour of the
    compiler on DEFMACRO have to be specified?
    I don't think that CLHS tends to specify such esoteric implementation
    details and for good reason. If you want a fresh &rest list you can
    trivially create one so why should the CLHS specify anything ?
    Are there any problems in required it to cons up a new &rest list for
    each expansion?
    It's not a good idea for a standard to specify implementation details.

    Yes of course, but this particular thing would make the macro form have
    the same meaning as it would have if it were not part of a macro.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)