0

I'm learning SICP and do the programming exercises. I have a question about exercise 4.5. The exercise 4.5 is:

Scheme allows an additional syntax for cond clauses, (<test> => <recipient>). If <test> evaluates to a true value, then <recipient> is evaluated. Its value must be a procedure of one argument; this procedure is then invoked on the value of the <test>, and the result is returned as the value of the cond expression. For example:

(cond 
  ((assoc 'b '((a 1) (b 2))) => cadr)
  (else false))

As shown above,if <test> is true,the value of the cond clause should be (<recipient> <test>) (i.e.

then <recipient> is evaluated. Its value must be a procedure of one argument; this procedure is then invoked on the value of the <test>, and the result is returned...

But when I search the solution on the Internet, almost all I found are (list (extended-cond-recipient first) (extended-cond-test first)). It's a list consist of <recipient> and <test> , not a function call. What should I do? It has troubled me a long time...

Alex Knauth
  • 8,133
  • 2
  • 16
  • 31
  • The "additional syntax" is not commonly used, almost everyone just uses the basic syntax. So it's not surprising you can't find much about it. – Barmar Dec 22 '17 at 20:12

1 Answers1

2

In The Core of the Evaluator, under “Special Forms”, is written:

• A case analysis (cond) is transformed into a nest of if expressions and then evaluated.

That is, first a transformation at the program level is done, and only after this transformation the resulting expression is evaluated. The transformation is done by the function cond->if, which does not evaluate the cond expression, only transform it in a nested list containing multiple if. This can be seen in the definition of the eval function, where there is the case:

((cond? exp) (eval (cond->if exp) env))

In the solutions that you have seen, the cond->if function is modified so that it transforms the => syntax in a list (as you have correctly observed), a list that contains the function as first element, and its argument as second element, and that list will be evaluated correctly in the subsequent steps of the interpreter.

Renzo
  • 26,848
  • 5
  • 49
  • 61
  • emm...the code example of the sicp is `(cond ((assoc 'b'((a 1) (b 2)))=> cadr) (else false)) `.As shown above,`(list (extended-cond-recipient first) (extended-cond-test first))`,is finally executed `(list cadr '(b 2))`.It's the **expression sequences**,and the value is the last sequence,i.e `(b 2)`.I think the answer should be like `(apply )`,rather than `(list )`.I've tried it,but failed... – sfailsthy Dec 23 '17 at 04:15
  • The result of `list cadr '(b 2))` is: `(cadr '(b 2))`, which is evaluated to 2 *only* when everything is expanded, by the line that I cited in the answer (the part `(eval (cond-if exp) env)`. I do not understand what are you trying to do: when the exercise says: “Modify the handling of cond” it means: modify the function `cond->if`. And in that function *there is no evaluation or application*. It is like a macro which is expanded, and the treatment of the `=>` syntax must be done at that level. *Nothing* must be evaluated or applied during such expansion. – Renzo Dec 23 '17 at 11:03