![]() |
![]() |
|
home—info—lectures—exams—hws—archive
Last time: passing 'sort' a function; functions as first-class values; filter; lambda (to make a function that couldn't exist at compile time, because part of its behavior required using a parameter.) let* list shorthand (list; quote(') quasiquote(`) unquote(,) unquote-splice(,@)) Java: varargs, autoboxing, Arrays.asList. Example: generalized 'max'.
We've seen how aggregate types, union types, and recursive data def'ns come together to make recursion-on-lists straightforward. "But why not just use iteration?" Answer: this technique extends to all structurally-recursive data: trees, as well as lists. (And, for parsing, where we'll have trees of complicated types.)
(I) family-trees (or "ancestor-trees") - work on examples lect05a.ss/ (II) same tree problems in Java. (III) refine our idea of "loops" to name four common cases: map, filter, fold (and, for-each); Tail recursion
; In scheme: (define (sum-all nums) (cond [(empty? nums) 0] [(cons? nums) (+ (first nums) (sum-all (rest nums)))])) // In Java: int sumAll( List<Integer> nums ) { int ssf = 0; // "sum-so-far" while (!nums.isEmpty()) { ssf = ssf + nums.get(0); nums = nums.sublist(1,nums.length()); } return ssf; }
How do these two implementations differ? First, let's work the scheme version through the stepper, on a list of 10 numbers: - We have a stack of pending work! - The scheme adds right-to-left, while Java adds left-to-right. - the java is udpating (mutating) ssf, nums as we procede. - the java might overflow int :-) This is a big problem for scheme, building up all that stack space! We can fix this by re-writing the scheme version: ; In scheme: (define (sum-all-v2 nums) (help-sum nums 0)) (define (help-sum nums ssf) (cond [(empty? nums) ssf] [(cons? nums) (help-sum (rest nums) (+ (first nums) ssf)))])) (filter, fold, map) Types. ... vs foldr Compare: (define (draw-fires-l lof scene) (if (empty? draw-fires) empty (draw-fire (first fire) (draw-fires (rest lof) scene)))) (define (draw-fires-r lof scene) (if (empty? draw-fires) empty (draw-fires (rest lof) (draw-fire (first fire) scene)))) Step through the two versions. The function second is *tail-recursive*. It's just like a loop! (for-each) In the 2nd version, 'scene' serves as an "accumulator variable", Grammar; parse trees.
Python:>>> lambda x : x+1 <function <lambda&rt; at 0x53df0&rt; >>> (lambda x : x+1)(3) 4
home—info—lectures—exams—hws—archive
©2009, Ian Barland, Radford University Last modified 2009.Feb.23 (Mon) |
Please mail any suggestions (incl. typos, broken links) to ibarland ![]() |
![]() |