1 Crucial tips on using Dr Racket, part 2
1.1 Automatic indentation
2 Actual Brain Exercise

Lab 3

1 Crucial tips on using DrRacket, part 2

1.1 Automatic indentation

Another advantage of a parenthesized language is that the editor can determine the right indentation for a line. Hitting the <tab> does not insert a tab; instead, it "re-indents" the current line by changing the amount of whitespace at the front of the line. It doesn’t matter where on a line the cursor is when you hit <tab>.

Also, when you highlight a whole region and hit <tab>, the entire region will be re-indented. Using <shift>-<option>-<right> to highlight a whole function definition and then hitting <tab> is a quick way to re-indent a whole big chunk of code at once. Use these keys to re-indent this block:

(define (go digit-rot-placements)
(let/ec break
(let loop ([digits-to-place digit-rot-placements]
 [placements empty])
 (cond [(empty? digits-to-place)
 (break placements)]
 [else
 (define l (length digits-to-place))
 (cond [(= l 8) (printf "x\n")]
 [(= l 7) (printf "y")])
 (let loop2 ([possible-placements (first
 digits-to-place)])
 (cond
 [(empty? possible-placements)
 #f]
 [else
 (define pts (first possible-placements))
 (cond [(free-points? pts search-box)
 (begin
 (points-take! pts search-box)
 (loop (rest digits-to-place)
 (cons pts placements))
 (points-release! pts search-box)
 (loop2 (rest
 possible-placements)))]
 [else (loop2 (rest
 possible-placements))])]))]))))

Along similar lines, when you hit <return>, DrRacket will put the cursor in what it believes to be the right place. When it puts the cursor in a place that surprises you, that’s probably a signal that your parens are not closed the way you expected them to be. For instance, suppose you’re trying to develop a function that adds two numbers together, and you type the first line as:

(define (add-nums a b))

... note the extra closing paren. Then, when you hit return, you’ll notice that the cursor goes all the way back over to the left edge, rather than being indented. That’s a clue to you that your definition was inadvertently closed off.

2 Actual Brain Exercise

  1. Define the AE language we described in class.

  2. Develop the evaluation method we described in class.

  3. Develop the method num-nums, that accepts an AE and returns a number indicating how many numbers it contains.

  4. Develop the method num-adds, that accepts an AE and returns the number of additions it contains.

  5. Develop the method swap-adds, that accepts an AE and returns a new AE where the left and right terms of every addition are swapped.

  6. Develop a representation for fruits; A fruit can be either a lemon, a melon, or a nomel. Each one has a single field that is a number [*]. Define these using a define-type.

  7. Develop the function onlyLemons, that consumes a list of fruits and returns a list containing only the lemons.

  8. Develop the function onlyMelons, that consumes a list of fruits and returns a list containing only the melons.

  9. Abstract over the two of these to obtain the function onlyThese, that consumes a list of fruits and a particular fruit predicate f (e.g., lemon?)and returns a list containing only those elements of the list that satisfy f. Show me this function when you’re finished with it, for lab credit.

When you’re done with these, demo them for lab credit.

If you have time, try these somewhat more advanced problems.

  1. Develop the my-append function that consumes two lists and returns the result of appending the second one to the first. So, if called with the list [a,b,c] and the list [d,e,f], it would return [a,b,c,d,e,f].

  2. Develop the my-take function that consumes a list and a number n and returns the first n elements of the list. If the list contains fewer than n elements, it returns the entire list.

  3. Develop the my-drop function that consumes a list and a number n and returns the list that remains after the first ’n’ elements of the input list. If the length of the input list is <= n, this function returns an empty list.

[*] I don’t care what the field is called. Actually, I don’t care whether they have fields or not, but experience shows that constructors with no arguments along with higher-order procedures confuse the heck out of students just getting used to Racket. If this doesn’t make sense to you, just take my advice and make up a field for each one.