# Question about macro order expansion

**URL:** <https://racket.discourse.group/t/question-about-macro-order-expansion/2259>\
**Category:** General\
**Created:** [August 30, 2023, 11:05am UTC](https://racket.discourse.group/t/question-about-macro-order-expansion/2259 "2023-08-30T11:05:14Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [August 30, 2023, 11:05am UTC](https://racket.discourse.group/t/question-about-macro-order-expansion/2259/1 "2023-08-30T11:05:14Z")

</div>

i have this macro i just modified:

```scheme
;; "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:

```scheme
((_ (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:

```scheme
(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:

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

```

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [August 30, 2023, 12:13pm UTC](https://racket.discourse.group/t/question-about-macro-order-expansion/2259/2 "2023-08-30T12:13:18Z")

</div>

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:

```scheme
#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

```

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [August 30, 2023, 1:16pm UTC](https://racket.discourse.group/t/question-about-macro-order-expansion/2259/3 "2023-08-30T13:16:56Z")

</div>

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 🤔.

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [August 30, 2023, 1:29pm UTC](https://racket.discourse.group/t/question-about-macro-order-expansion/2259/4 "2023-08-30T13:29:33Z")

</div>

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 `...+`.

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [August 30, 2023, 7:49pm UTC](https://racket.discourse.group/t/question-about-macro-order-expansion/2259/5 "2023-08-30T19:49:37Z")

</div>

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.
