Reputation: 29
Given the following code:
(define (my-if condition iftrue iffalse)
(cond (condition iftrue)
(else iffalse)))
'-----example1
(my-if #t
(display "my if was true!")
(display "my if was false!"))
(newline)
'-----example2
(my-if #t
(display "my if was true!")
(+ 2 3))
why would example 1 evaluate both parameters right away giving an output of
my if was true!my if was false!
yet in example 2 only
my if was true!
is the output?
Is this because display
is never delayed but arithmetic operators are, or is it something else?
Upvotes: 1
Views: 246
Reputation: 135287
Not sure if you can use lazy racket, but if so, this will work for you
#lang lazy
(define (my-if p t f)
(cond [p t]
[else f]))
(my-if #t (display 'true) (display 'false))
; => true
If you run it in normal racket ...
#lang racket
(define (if p t f)
(cond [p t]
[else f]))
(if #t (display 'true) (display 'false))
; => truefalse
Another way you could achieve laziness would be wrapping the arguments in lambdas:
#lang racket
(define (my-if p t f)
; this calls the correct function with zero arguments
((if p t f)))
; wrap the delayed arguments in zero-argument functions
(my-if #t (λ () (display 'true)) (λ () (display 'false)))
; => true
Upvotes: 1
Reputation: 236034
In both cases both arguments get evaluated - that's how procedures work, all the arguments to a function call are evaluated before the function body is executed, they are never delayed! (unless explicitly done so).
And that's why you can't implement my-if
as a procedure, it has to be a special form, like if
and cond
, which only evaluate the part corresponding to a true condition, or the else
part if none is true. Also, bear in mind that display
just prints its argument on the console, but it doesn't return any value.
Your second example prints the message, but the addition too got executed anyway, it's just that its value wasn't returned because the first condition was true, so my-if
returns the value of its first parameter, which is a value returned from the display
call (before my-if
is entered), which is void. For instance, see what this outputs on the console:
(my-if #t
(+ 2 3)
(display "my if was false!"))
As expected, both parameters get evaluated, but only the first one's value is returned:
my if was false! ; this got printed anyway
5 ; this is the value returned by `my-if`
Upvotes: 3