7  Thursday Morning: Some Basic I/O

7.1  Goal: Shriram’s Day of Networking

to understand how Scheme programs can communicate with the rest of the world via sequential reading and writing

7.2  apply, another powerful loop


(+ 2 3)

add 2 and 3


(+ 2 3 4 5 6 7)

add 2, ..., and 7, because prefix syntax is good


(+ (list 2 3 4 5 6 7))

error. Even though + can “do” a sequence of numbers, it can’t deal with lists.


;; sum : (Listof Number)  →  Number
;; add up the numbers in a list 
(define (sum l) 
  (apply + l))

;; tests
(= (sum (list 1 2 3)) 6)

With apply, we can do it anyway. Say we “launch” the sum application on (list 1 2 3),

  (sum (list 1 2 3))
= (apply + (list 1 2 3))
= (+ 1 2 3)

So apply does “the right thing.”


;; average : (Listof Number)  →  Number
;; the average for a non-empty list,
;; error otherwise
(define (average l)
  (cond
    [(empty? l) (error ...)]
    [else (/ (apply + l) (length l))]))

Yes, this is the two-line expert version of average.


;; largest :
;;          (NEListof Number)  →  Number
;; the largest item on the list 
(define (largest l) (apply max l))

Yes, it’s one line long.


;; sentence :
;;      (Listof String) String  →  String
;; separate the words
;;      with a leading space,
;; add a "." at the end
(define (sentence l end)
  (string-append 
    (apply string-append 
           (map (lambda (word)
		  (string-append
		    " " word))
	        l))
    end))

;; tests:
(string=?
  (sentence
    (list "hello" "world") "!")
  " hello world!")
(string=?
  (sentence
    (list "how" "are" "you") "?")
  " how are you?")

Imagine doing this without apply and lambda.


But, always remember, you don’t really ever need loops.

You can always design a function instead of using a loop.