user3427479
user3427479

Reputation: 11

Racket Programming - my map

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

Answers (3)

GoZoner
GoZoner

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

Óscar López
Óscar López

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

Sylwester
Sylwester

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

Related Questions