Question about macro order expansion

i have this macro i just modified:

;; "abcdefgh"
;; > {s[2 * 3 - 4 $ 2 * 3 + 1 $ 2 * 4 - 6] <- "0000"}
;; "ab0d0f0h"

;; $bracket-apply$ is from SRFI 105  bracket-apply is an argument of the macro
(define-syntax <-
  
  (syntax-rules ()


    ((_ (kar kdr) expr) ; expr must be a pair

     (begin
       (set! kar (car expr))
       (set! kdr (cdr expr))))
    

    
    ;;  special form like : (<- ($bracket-apply$ T 3) ($bracket-apply$ T 4))
    ;; We will let the second $bracket-apply$ be executed and forbid the execution of first $bracket-apply$.
    
    ;; one dimension array, example: {a[4] <- 7}
    ;; $bracket-apply$ is from SRFI 105  bracket-apply is an argument of the macro
    ((_ (bracket-apply container index ...) expr)

     (begin

       ;; add a checking
       ;; (define x 3)
       ;; > (<- (aye x 3) 7)
       ;; . . ../Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/required-files/assignment.rkt:1:6: Bad <- form: the LHS of expression must be an identifier or of the form ($bracket-apply$ container index) , first argument  'aye " is not $bracket-apply$."
       (unless (equal? (quote $bracket-apply$) (quote bracket-apply)) 
	       (error "Bad <- form: the LHS of expression must be an identifier or of the form ($bracket-apply$ container index ...) , first argument is not $bracket-apply$:"
		      (quote bracket-apply)))

       (parse-square-brackets-arguments-and-assignment container expr index ...)))
    

    
    
    ;;(<- x 5)
    ((_ var expr)
     
     (begin
       ;;(display "<- : variable set!") (newline)
       (set! var expr)
       var))

    
    ;; (declare x y z t)
    ;; {x <- y <- z <- t <- 7}
    ;; 7
    ;; (list x y z t)
    ;; (7 7 7 7)

    ;; > (require srfi/25)
    ;; > {I <- (make-array (shape 0 4 0 4))}
    ;; #<array:srfi-9-record-type-descriptor>
    ;; > {I[0 0] <- I[1 1] <- I[2 2] <- I[3 3] <- 1}
    ;; 1
    ;; > {I[0 0]}
    ;; 1
    ;; > {I[0 1]}
    ;; 0
    ;; > I
    ;; #<array:srfi-9-record-type-descriptor>
    
    ((_ var var1 ... expr)
     
     (<- var (<- var1 ... expr))) 
     
    ))


i just added the first case:

((_ (kar kdr) expr) ; expr must be a pair

     (begin
       (set! kar (car expr))
       (set! kdr (cdr expr))))
    

and it works but my idea was that the place of this case could be in second position as there is no possible confusion ,the number of args in the first nested expression in parenthesis being not the same: (kar kdr) versus (bracket-apply container index ...)

but in fact no , if i do that it fails:

(declare a b)
{(a b) <- (cons 7 8)}
In procedure raise-exception:
Bad <- form: the LHS of expression must be an identifier or of the form ($bracket-apply$ container index ...) , first argument is not $bracket-apply$: a

good evaluation:

> (declare a b)
> '{(a b) <- (cons 7 8)}
'(<- (a b) (cons 7 8))
> {(a b) <- (cons 7 8)}
> a
7
> b
8

The clauses in syntax-rules and syntax-case have the form:

[pattern result]

Both syntax-rules and syntax-case tries to match the input syntax object
with the pattern in the order the appear. When the first pattern is found
the corresponding result is used.

Consider:

#lang racket

(syntax-case #'(a b) ()
  [(x y) 'list-of-two-elements]
  [var   'identifier-matches-all])
; => 'list-of-two-elements


(syntax-case #'(a b) ()
  [var   'identifier-matches-all]
  [(x y) 'list-of-two-elements])

; => 'identifier-matches-all

on your example i agree , it is right because '(a b) can be interpreted both as var or
(x y) but i can not understand in my macro why (a b) can be interpreted as
(bracket-apply container index ...) as the latest contains at least 3 elements:
bracket-apply
container
index
but (a b) contains only 2.

Unless the pattern matching schema does not care of number of elements in the sub expressions :thinking:.

In the pattern (bracket-apply container index ...), index can match 0 times. So (a b) binds to (bracket-apply container).

To force at least one match, use (bracket-apply container index0 index...) or syntax-parse's ...+.

1 Like

d'accord (ok) i did not know that, i revisited all my macros, i uderstand why i had sometimes problem with ellipsis, it is counterintuitive that index can count for zero times. now i understand.