Reputation: 11
How would you replace the cond
to an if else
in this program?
#lang racket
(define (my-map f lst)
(cond
[(empty? lst) empty]
[else (cons (f (first lst))
(my-map f (rest lst)))]))
Upvotes: 1
Views: 518
Reputation: 70235
Racket isn't really Scheme as, for example, Racket requires a different if
syntax than Scheme. But, figuring that you are, in fact, learning Scheme you might check out the Scheme R7RS Specification; it provides a definition of cond
in terms of if
. Here is a definition that I've simplified for you by axing templates involving '=>':
(define-syntax cond
(syntax-rules (else)
((cond (else result1 result2 ...))
(begin result1 result2 ...))
((cond (test)) test)
((cond (test) clause1 clause2 ...)
(let ((temp test))
(if temp temp
(cond clause1 clause2 ...))))
((cond (test result1 result2 ...))
(if test (begin result1 result2 ...)))
((cond (test result1 result2 ...)
clause1 clause2 ...)
(if test
(begin result1 result2 ...)
(cond clause1 clause2 ...)))))
Beautiful, yes?
Upvotes: 0
Reputation: 236140
A cond
expression with just one condition and a single expression as the consequent and an else
part with a single expression as the alternative can be easily transformed into an if
expression. For example, this:
(cond (<cond1> <exp1>)
(else <exp2>))
Is equivalent to this:
(if <cond1> ; condition
<exp1> ; consequent
<exp2>) ; alternative
In particular, your code can be rewritten as:
(define (my-map f lst)
(if (empty? lst)
empty
(cons (f (first lst))
(my-map f (rest lst)))))
Also notice that a cond
is just a shorter way to express a series of nested if
expressions. Think of it as a shorthand for IF-ELSE IF-ELSE IF-ELSE
in other programming languages. In fact, for the general case many interpreters implement this:
(cond (<cond1> <exp1> <exp2>) ; we can have any number of conditions
(<cond2> <exp3> <exp4>) ; and any number of expressions after condition
(else <exp5> <exp 6>))
... As a syntactical transformation that (ignoring the =>
syntax) gets expanded into:
(if <cond1>
(begin
<exp1>
<exp2>)
(if <cond2>
(begin
<exp3>
<exp4>)
(begin ; the last expression is the `else` part
<exp5>
<exp6>)))
Notice that the expressions after each condition are inside a begin
form, meaning that in a cond
they're implicitly inside a begin
- so you can write more than one! whereas in an if
expression only a single expression can go in either the consequent or the alternative, and if more than one is needed a begin
must be used. As always, refer to the documentation for more details.
Upvotes: 1
Reputation: 48775
Every cond:
(cond (predicate consequent)
(predicate2 consequent2-1 consequent2-2)
(else alternative))
Can be rewritten:
(if predicate
consequent
(if predicate2
(begin
consequent2-1
consequent2-2)
alternative))
Your example becomes particularly simple because there is not more than 2 clauses and the code does not make use of explicit begin.
Upvotes: 0