Reputation: 897
#!/usr/bin/env racket
#lang racket/base
;Define a procedure that takes three numbers as arguments and returns the sum of the
;squares of the two larger numbers.
(define (procsq a b c)
(when (and (< a b)(> c a))(+ (* b b)(* c c)))
(when (and (< a c)(> b a))(+ (* b b)(* c c)))
(when (and (< b a)(> c b))(+ (* a a)(* c c)))
(when (and (< b c)(> a b))(+ (* a a)(* c c)))
(when (and (< c a)(> b a))(+ (* a a)(* b b)))
(when (and (< c b)(> a c))(+ (* a a)(* b b))))
(displayln (procsq 1 2 3)); Why does it print #<void> ?
(displayln (procsq 3 2 1))
(displayln (procsq 3 1 2)); Why does it print #<void> ?
I coded my answer using when, why doesn't it work? The comments show with what arguments it doesn't work.
Upvotes: 0
Views: 88
Reputation: 71065
Normally, a procedure returns the value of the last expression in the body, as is explained in the other answer.
In many other languages though we have the ability to return immediately from within the depths of a running procedure. Scheme too has such capability, though not through a keyword but what's known a continuation mechanism:
(define (procsq a b c)
(call-with-current-continuation
(lambda (return)
(when (and (< a b)(> c a)) (return (+ (* b b)(* c c))))
(when (and (< a c)(> b a)) (return (+ (* b b)(* c c))))
(when (and (< b a)(> c b)) (return (+ (* a a)(* c c))))
(when (and (< b c)(> a b)) (return (+ (* a a)(* c c))))
(when (and (< c a)(> b a)) (return (+ (* a a)(* b b))))
(when (and (< c b)(> a c)) (return (+ (* a a)(* b b)))))))
;; > (procsq 1 2 3)
;; 13
Upvotes: 1
Reputation: 780724
A procedure returns the value of the last expression in the body. Each when
is calculating a value, but they're not being returned because it's not the last expression. It then goes to the next when
. The result is the value of the last when
, which will be #<void>
if the condition isn't true.
Use cond
when you have a series of mutually-exclusive conditions, not separate when
expressions. It will return the value corresponding to the first condition that's true.
(define (procsq a b c)
(cond ((and (< a b)(> c a)) (+ (* b b)(* c c)))
((and (< a c)(> b a)) (+ (* b b)(* c c)))
((and (< b a)(> c b)) (+ (* a a)(* c c)))
((and (< b c)(> a b)) (+ (* a a)(* c c)))
((and (< c a)(> b a)) (+ (* a a)(* b b)))
((and (< c b)(> a c)) (+ (* a a)(* b b)))))
Upvotes: 3