Source code Jakub T. Jankiewicz (23 Jan 2024 00:59 UTC)
Re: Source code Jens Axel Søgaard (23 Jan 2024 01:24 UTC)
Re: Source code Jens Axel Søgaard (23 Jan 2024 01:48 UTC)
Re: Source code Jakub T. Jankiewicz (23 Jan 2024 19:48 UTC)
Re: Source code Wolfgang Corcoran-Mathe (23 Jan 2024 19:17 UTC)
Re: Source code Jakub T. Jankiewicz (23 Jan 2024 19:46 UTC)
Re: Source code Wolfgang Corcoran-Mathe (23 Jan 2024 22:10 UTC)

Source code Jakub T. Jankiewicz 23 Jan 2024 00:58 UTC

Hi,

I have a question about the provided implementation:

(define-syntax apply/mv
  (syntax-rules ()
    ((apply/mv operator operand1 ... producer)
     (letrec-syntax
         ((aux (syntax-rules ::: ()
                 ((aux %operator () ((%operand1 arg1) :::) %producer)
                  (let-values (((proc) %operator)
                               ((arg1) %operand1) :::
                               (args %producer))
                    (apply proc arg1 ::: args)))
                 ((aux %operator (%operand1 operand2 :::)
                                 (temp :::) %producer)
                  ;; args1 is not defined
                  (aux %operator (operand2 :::) (temp ::: (%operand1 arg1))
                       %producer)))))
       (aux operator (operand1 ...) () producer)))))

(define-syntax call/mv
  (syntax-rules ()
    ((call/mv consumer producer1 ...)
     (letrec-syntax
         ((aux (syntax-rules ::: ()
                 ((aux %consumer () ((%producer1 args1) :::))
                  (let-values (((proc) %consumer)
                               (args1 %producer1) :::)
                    (apply proc (append args1 :::))))
                 ((aux %consumer (%producer1 producer2 :::) (temp :::))
                  (aux %consumer (producer2 :::)
                                 ;; args1 is not defined
                                 (temp ::: (%producer1 args1)))))))
                                 (aux consumer (producer1 ...) ())))))

It looks like args1 in both macros is unbound. I'm not an expert in Scheme
hygienic macros but I'm pretty comfortable with them, and it looks like an
error. The macros did work, but I'm not sure if the code is correct. I'm also
not sure if I fully understand how those macros work.

Where the args1 name (from last nested syntax) come from?

The same happen with set!-values macro but with temp1 symbol:

(define-syntax set!-values
  (syntax-rules ()
    ((set!-values (var1 ...) producer)
     (letrec-syntax
         ((aux (syntax-rules ::: ()
                 ((aux () ((%var1 temp1) :::) %producer)
                  (let-values (((temp1 ::: . temp*) %producer))
                    (set! %var1 temp1) :::))
                 ((aux (%var1 var2 :::) (temp :::) %producer)
                  ;; temp1 is not defined here
                  (aux (var2 :::) (temp ::: (%var1 temp1)) %producer)))))
       (aux (var1 ... ) () producer)))
    ((set!-values (var1 ... . var*) producer)
     (letrec-syntax
         ((aux (syntax-rules ::: ()
                 ((aux () ((%var1 temp1) ::: (%var* temp*)) %producer)
                  (let-values (((temp1 ::: . temp*) %producer))
                    (set! %var1 temp1) :::
                    (set! %var* temp*)))
                 ((aux (%var1 var2 :::) (temp :::) %producer)
                  ;; temp1 is not defined here
                  (aux (var2 :::) (temp ::: (%var1 temp1)) %producer)))))
       (aux (var1 ... var*) () producer)))
    ((set!-values var* producer)
     (let-values ((temp*) producer)
       (set! var* temp*)))))

I hope that this is not something that yet to learn about Hygienic macros.

--
Jakub T. Jankiewicz, Senior Front-End Developer
https://jcubic.pl/me
https://lips.js.org
https://koduj.org