Dan D.
Dan D.

Reputation: 8557

How to redefine Scheme/Racket fundamental forms?

Racket has built-in fundamental form 2-arm if, but it doesn't have the word else, so I want to add the else word to it.

This code works:

(require syntax/parse/define)
(define-syntax-rule (myif Cond Form1 else Form2)
  (if Cond Form1 Form2)
)

(myif #t (displayln 1) else (displayln 2))

However myif is undesired as keyword, changing it to if raises error:

if: use does not match pattern: (if Cond Form1 else Form2)
in: (if #t (displayln 1) (displayln 2))

How to redefine the form if?

Upvotes: 1

Views: 137

Answers (2)

Sorawee Porncharoenwase
Sorawee Porncharoenwase

Reputation: 6502

The answer above is "correct" at some level, but there are some mistakes.

  1. define-syntax-rule is not from syntax/parse/define. If you want to use define-syntax-rule, there's no need to (require syntax/parse/define).

  2. What will happen when I call (if #t 1 2 3) with your if? else in your macro is a pattern variable, so it can match against anything. Do you intend to allow this to happen? If not, this is where you can use the features of syntax/parse/define. You can write:

    (require syntax/parse/define)
    (define-simple-macro (if test-expr:expr 
                             {~datum then} 
                             then-expr:expr 
                             {~datum else} 
                             else-expr:expr)
      (racket:if test-expr then-expr else-expr))
    

    So (if 1 then 2 else 3) will expand to (racket:if 1 2 3), but (if 1 0 2 0 3) will fail with an error.

Upvotes: 2

Dan D.
Dan D.

Reputation: 8557

Thanks @AlexKnauth for the comment, I can redefine if as below:

(require syntax/parse/define)
(require (only-in racket/base [if r-if]))

(define-syntax-rule (if Cond Form1 else Form2)
  (r-if Cond Form1 Form2)
)

(if #t (displayln 1) else (displayln 2))

Upvotes: 1

Related Questions