Reputation: 11
Defining the function my-if
to use cond
internally results in different behavior than using cond
directly.
Using cond
, the DrRacket interpreter only prints the string for the first displayln
.
Code:
(cond
(#t (displayln "Cond: should run"))
(else (displayln "Cond: shouldn't run")))
Output:
Cond: should run
Using my-if
, the DrRacket interpreter prints both of the strings, despite seeming (at least to me) that it should expand to the same code.
Code:
(define (my-if condition statement-if statement-else)
(cond (condition statement-if)
(else statement-else)))
(my-if
#t
(displayln "My-If: should run")
(displayln "My-If: shouldn't run"))
Output:
My-If: should run
My-If: shouldn't run
I assumed that the function created by define
would expand to the same code as the cond
, but given that it has a different result, I assume it didn't.
Given that the 2 versions of the code have different results, my guess is something related to eager/lazy evaluation or cond
being a macro in and of itself.
Upvotes: 1
Views: 125
Reputation: 1969
Function application in Racket is evaluated in the following way:
Since you're writing (my-if #t (displayln "should") (displayln "shouldn't"))
, each of the arguments (including both displayln
s) are evaluated first.
This is why you can't define conditionals as a function. What you're really looking for is Racket's macro system. You can then define my-if
as a macro in the following way:
#lang racket
(define-syntax-rule (my-if c t e)
(cond
[c t]
[else e]))
(my-if #t (displayln "should run") (displayln "shouldn't run"))
Note that unlike function application, which evaluates the arguments first, a macro is actually expanded syntactically (in Racket, also hygenically).
Upvotes: 2