[plt-scheme] Half-book review of HtDP

From: Hector E. Gomez Morales (hectorgm at ciencias.unam.mx)
Date: Fri Jun 25 06:05:01 EDT 2004

Warning this review is up to the middle of the book.
Sorry for the gap between post but I have been very busy in school.

Hi:

I think every review is very for the most part subjective to the
experiences and knowledge of the reviewer so I will put in short my
background.

I am a freshman of Computer Science my first programming language was
fortran then I learned C++ and some C# i know too, no functional
programming, lisp or scheme knowledge I had before the reading of HtDP.
I started to read the book by recommendation of a friend.

For the post part the book does his job well, little by little
introduces syntax, semantics, etc of scheme in a way that is painless
and straight forward to the reader, the curve of learning is more
applicable to the use of drscheme specially in the first sections. In
parallel the reader is shown good design methods that not only are
applicable to functional programming but to programming in general in my
case some of this methods are unit testing, the use of contracts, the
use of data definitions and finally the guideline for making auxiliary
functions. Each section builds from the previous ones so the exercises
become more challenging but more rewarding when they are finished.
The sections 11 and 23 are the ones I have liked  the most for the
simple reason that the combination of mathematics and scheme is pretty
strong for grasping concepts very rapidly. I think that some type of
cheat-sheet in the end of the book (Something like the rule and
commandments if the Little Schemer) of the Guidelines and the various
design recipes could be of great help. Overall I really liked the book,
especially the tone and feel is relaxed and unpretentious. I think that
the second half is going to be equally good so I think this book is a
good intro book to scheme and programming without a doubt.  

The not so good things in my journey through the book have been:

- The use of certain names for various functions: For example find,
how-many, depth, etc this names are repeated various times to name
functions, even when one function searches in a list of structures and
another searches in a web page. A more specific name for each one could
minimize the need to rename functions to avoid name-clashes.

- From the start from section 10 to the end of section 17 no easy way to
test functions that output lists: From section 10 the reader is
introduced to functions that output lists put there is no hint or note
of how to make the verification of this output manageable. I think a
note or hint that told the reader about the existence of equal? would be
the best course of action, like when in some exercises in hints is told
the existence of append before the how-to of processing two lists
simultaneously is brought to the reader.

Hector Gomez M

PD. I have attached a text file with various possible errors and/or
typos that I have cached in my reading of the web edition of the book. 
-------------- next part --------------
Error and/or typos in the online version of HtDP.

Part II, Section 10 -> Figure 29
The column item is incorrect all three fields are robot and should be robot, doll and rocket.


Part IV, Section 19 -> Exercise 19.2.3

19.2.3.   Here is a structure definition for pairs

(define-struct pair (left right))

and its parametric data definition:
...

There is a problem with this structure definition, in this part of the book the student is using the Intermediate Language that has the primitive
pair? this conflicts when trying to execute with the struct-definition of the exercise because by default it makes the pair? predicate for the structure so conflict raises about trying to redefine a primitive.


Part IV, Section 21 -> 21.4 Extended Exercise: Moving Pictures, Again

...

Develop the program lunar-lander. It places LUNAR at the top of a canvas and then uses the modified functions to move the lander up or down.

Use the teachpack arrow.ss to give users control over how fast and when the lunar lander should move:

(start 500 100)
(draw LUNAR)
(control-up-down LUNAR 10 move-lander draw-losh)

...

The student develops the program lunar-lander to move the LUNAR list-of-shapes up and down the canvas but in the example of how to use the function in arrow.ss the example uses the move-lander function instead of lunar-lander. So it should be:

...

Develop the program lunar-lander. It places LUNAR at the top of a canvas and then uses the modified functions to move the lander up or down.

Use the teachpack arrow.ss to give users control over how fast and when the lunar lander should move:

(start 500 100)
(draw LUNAR)
(control-up-down LUNAR 10 lunar-lander draw-losh)

...

Part IV, Section 22 -> 22.3  A First Look at Graphical User Interfaces

...

How all this works is best illustrated with examples. Our first example is a canonical GUI program:

(create-window (list (list (make-button "Close" hide-window))))

...

The problem is that the hide-window call-back function takes a parameter that has to be a window (that one wants to close) so this flags an error when executed.
From the GUI doc is a example using hide-window:

(define w (create-window (list (list (make-button "QUIT" (lambda (e) (hide-window w)))))))

But alas the student cannot use lambda-expressions yet in this part of the book. (Intermediate Language)


Part V, Section 25 -> Figure 66

;; draw-and-clear : a-ball  ->  true
;; draw, sleep, clear a disk from the canvas 
;; structural design, Scheme knowledge

should be:

;; draw-and-clear : ball  ->  true
;; draw, sleep, clear a disk from the canvas 
;; structural design, Scheme knowledge

Part V, Section 25.1 

;; out-of-bounds? : a-ball  ->  boolean
;; to determine whether a-ball is outside of the bounds
;; domain knowledge, geometry
(define (out-of-bounds? a-ball)
  (not
   (and
     (<= 0 (ball-x a-ball) WIDTH)
     (<= 0 (ball-y a-ball) HEIGHT))))

should be:

;; out-of-bounds? : a-ball  ->  boolean
;; to determine whether a-ball is outside of the bounds
;; domain knowledge, geometry
(define (out-of-bounds? a-ball)
  (not
   (and
     (<= 0 (ball-x a-ball) WIDTH)
     (<= 0 (ball-y a-ball) HEIGHT))))

and

;; move-until-out : a-ball  ->  true
;; to model the movement of a ball until it goes out of bounds
(define (move-until-out a-ball) ...)

;; move-until-out : a-ball  ->  true
;; to model the movement of a ball until it goes out of bounds
(define (move-until-out a-ball)
  (cond
    [(out-of-bounds? a-ball) true]
    [else (and (draw-and-clear a-ball)
               (move-until-out (move-ball a-ball)))]))
               
should be:

;; move-until-out : ball  ->  true
;; to model the movement of a ball until it goes out of bounds
(define (move-until-out a-ball) ...)

;; move-until-out : ball  ->  true
;; to model the movement of a ball until it goes out of bounds
(define (move-until-out a-ball)
  (cond
    [(out-of-bounds? a-ball) true]
    [else (and (draw-and-clear a-ball)
               (move-until-out (move-ball a-ball)))]))

Part V, Section 26.3

;; gcd-structural : N[>= 1] N[>= 1]  ->  N
;; to find the greatest common divisior of n and m
;; structural recursion using data definition of N[>= 1] 
(define (gcd-structural n m)
  (local ((define (first-divisior-<= i)
	    (cond
	      [(= i 1) 1]
	      [else (cond
		      [(and (= (remainder n i) 0) 
			    (= (remainder m i) 0))
		       i]
		      [else (first-divisior-<= (- i 1))])])))
    (first-divisior-<= (min m n))))

(gcd-structural 101135853 45014640)

The result is 177 and to get there gcd-structural had to compare 101135676, that is, 101135853 - 177, numbers. This is a large effort and even reasonably fast computers spend several minutes on this task.

Exercise 26.3.1.   Enter the definition of gcd-structural into the Definitions window and evaluate (time (gcd-structural 101135853 45014640)) in the Interactions window.

Hint: After testing gcd-structural conduct the performance tests in the Full Scheme language (without debugging), which evaluates expressions faster than the lower language levels but with less protection. Add (require-library "core.ss") to the top of the Definitions window. Have some reading handy!

problems:

Well the gcd-structural first chooses (min m n) and uses it in the auxiliary function so it will compare 45014640-177 numbers not 101135853 - 177 numbers.
The step about adding (require-library "core.ss") is no longer needed, apart that the require syntax is very different in the last drscheme build (207).

Posted on the users mailing list.