Skip to content

Commit 57d3a4b

Browse files
Add solution to Exercise 2.77 (source-academy#241)
* Add solution to Exercise 2.77 * Edit typo, add one sentence for clarification * Edit error in math evaluation * Add scheme version for answer
1 parent f8ea21a commit 57d3a4b

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

xml/chapter2/section5/subsection1.xml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,77 @@ put("angle", list("complex"), angle);
465465
<SPLITINLINE><SCHEME>procedure</SCHEME><JAVASCRIPT>function</JAVASCRIPT></SPLITINLINE>
466466
is dispatched to
467467
in each case?
468+
<SOLUTION>
469+
Putting the above lines to the package will open up z, and those lines act as a pass-through. <SPLITINLINE><SCHEME><SCHEMEINLINE>apply-generic</SCHEMEINLINE></SCHEME><JAVASCRIPT><JAVASCRIPTINLINE>apply_generic</JAVASCRIPTINLINE></JAVASCRIPT></SPLITINLINE> ill be invoked twice. We shall trace with substitution model how the program evaluates.
470+
<SNIPPET EVAL="no">
471+
<JAVASCRIPT>
472+
magnitude(z);
473+
apply_generic("magnitude", list(z));
474+
// In this case:
475+
// type_tags = map(type_tag, list(z))
476+
// Which evaluates to:
477+
// type_tags = list("complex");
478+
// and
479+
// fun = get("magnitude", list("complex"));
480+
// which, due to the addition of the put("magnitude", list("complex"), magnitude);
481+
// fun = magnitude;
482+
apply(magnitude, map(contents, list(z)));
483+
apply(magnitude, pair("rectangular", pair(3,4)));
484+
magnitude(pair("rectangular"), pair(3,4));
485+
apply_generic("magnitude", list(pair("rectangular"), pair(3,4)));
486+
// type_tags = map(type_tag, list(z)) evaluates to list("rectangular")
487+
// fun = get("magnitude", list("rectangular")) which evaluates to
488+
// z => math_sqrt(square(real_part(z)) + square(imag_part(z)))
489+
// z => math_sqrt(square(head(z)) + square(tail(z)))
490+
apply(fun, map(contents, list(pair("rectangular"), pair(3,4))))
491+
apply(fun, pair(3,4))
492+
(z => math_sqrt(square(head(z)) + square(tail(z))))(pair(3,4));
493+
math_sqrt(square(head(pair(3,4))) + square(tail(pair(3,4))))
494+
...
495+
math_sqrt(square(3) + square(4));
496+
...
497+
math_sqrt(9 + 16);
498+
math_sqrt(25);
499+
5
500+
</JAVASCRIPT>
501+
<SCHEME>
502+
;;*** Use substitution rule:
503+
(magnitude z)
504+
505+
;;** First apply-generic:
506+
(apply-generic 'magnitude z) ;; where z is the whole objec including symbol 'complex.
507+
;;recall
508+
(define (apply-generic op . args)
509+
(let ((type-tags (map type-tag args)))
510+
(let ((proc (get op type-tags)))
511+
(if proc
512+
(apply proc (map contents args))
513+
(error
514+
"No method for these types -- APPLY-GENERIC"
515+
(list op type-tags))))))
516+
;; substitution
517+
(let ((type-tags '(complex)) ... ))
518+
(let ((proc (get op '(complex))) ... ))
519+
(let ((proc magnitude) ... ))
520+
(if proc... ;; true
521+
(apply magnitude (contents z))
522+
(magnitude z-prime) ;; where z-prime is the contents (the cdr) of the original object, that is, with the 'complex stripped off.
523+
524+
;;** Second apply-generic:
525+
(let ((type-tags '(rectangular)) ... ))
526+
(let ((proc (get op '(rectangular))) ... ))
527+
(let ((proc (get 'magnitude '(rectangular))) ... ))
528+
(let ((proc (lambda (z) (sqrt (+ (square (real-part z))
529+
(square (imag-part z)))))) ... )))
530+
531+
(if proc... ;; true
532+
(apply (lambda (z) (sqrt (+ (square (real-part z))
533+
(square (imag-part z))))) (contents z-prime))
534+
(sqrt (+ (square 3) (square 4)))
535+
5
536+
</SCHEME>
537+
</SNIPPET>
538+
</SOLUTION>
468539
</EXERCISE>
469540

470541
<EXERCISE>

0 commit comments

Comments
 (0)