I've been given two if-statements instructions in Racket:
(define (if-fun c thn els) (if c thn els))
(define-syntax-rule (if-mac c thn els) (if c thn els))
Would someone please mind explaining the differences between how these two if-statements are evaluated and provide an example using each if-statement definition? I'm having a hard time differentiating between how macros and function arguments are evaluated in this example. I've tried small examples such as:
(if-fun (> 3 4) true false) ;; #f
(if-mac (> 3 4) true false) ;; #f
But clearly that doesn't help me differentiate the two definitions.
-thanks
From your comment it sounds like you already figured this out. The key question is, when (if ever) do things get evaluated?
Another key point is that functions and macros are totally different, even though their definition and use can look the same.
The way you use a function and a macro appears exactly the same: (thing other stuff)
. It's not apparent whether thing
is a function or a macro. This is both good and bad. Mostly it's very good.
As for defining things, the way you define a macro using define-syntax-rule
is extremely similar to how you define
a function. This is both good and bad. I'd say it's mostly quite bad, when you're first learning -- because it makes it really easy to forget how completely different macros are from functions. It can be confusing!
When you call a function, at run time all of the arguments are evaluated, then given to the function. That's why an argument to if-fun
like (/ 1 0)
will cause an error. It is evaluated (and elicits a divide by zero error) before control even gets inside if-fun
.
(Sidenote: When you call a function with lazy evaluation, or with manual "thunks", then the evaluation is delayed. An if-lazy
is able to call either the thn
or els
procedure arguments, only as/when needed. When the condition is false, it doesn't even attempt to call els
.)
When you invoke a macro:
When: The macro does its work before your program even runs. The macro works at compile time, not later at run time.
What: A macro transforms pieces of code into other pieces of code. But the code isn't evaluated, yet. The code is evaluated only later, at run time. So the "arguments" to if-mac
aren't evaluated by the macro. They just get plugged into the code for the real if
form, which is a macro (or primitive special form) that evaluates only what is required.
The final confusing part is that, because your example's then and else expressions don't have any side effects and don't cause any error, the difference isn't apparent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With