Com S 342 meeting -*- Outline -*- * branching (3.3) ** cond (3.3.1) Might mention idea of structured programming: make the program match the problem idea ------------------------------------------ COND (3.3) problem: - nested ifs are hard to read - they don't match grammar well (define count-varrefs ;; TYPE: (-> (lambda-exp) number) (lambda (exp) (if (varref? exp) 1 (if (lambda? exp) (count-varrefs (lambda->body exp)) (+ (count-varrefs (app->rator exp)) (count-varrefs (app->rand exp))))))) (define count-varrefs ;; TYPE: (-> (lambda-exp) number) (lambda (exp) ------------------------------------------ (cond ((varref? exp) 1) ((lambda? exp) (count-varrefs (lambda->body exp))) (else (+ (count-varrefs (app->rator exp)) (count-varrefs (app->rand exp))))))) Q: How would you write this in C or C++? that language doesn't really provide something like cond, switch is not really the same, although similar but people make do with formatting conventions Some languages, like Algol 68 and CLU, provide elseif as a keyword if b then s1() elseif b2 then s2() else s3() end ------------------------------------------ SYNTAX ::= ( cond {}+ ) ::= ( ) ::= ( else ) ::= ::= SEMANTICS (cond (test1 body1) (test2 body2) ... (testn bodyn) (else bodye)) ------------------------------------------ write out the translation semantics actually, a body can have any number of expressions, there's an implicit begin there. ** case (3.3.2) ------------------------------------------ CASE (3.3.2) problem: comparing the value of expression to many numbers, chars, symbols is tedious (let ((pos (list-index x ls))) (cond ((= pos 0) 'first) ((= pos 1) 'second) ((= pos 2) 'third) ((or (= pos 3) (= pos 4)) 'higher) (else 'too-high))) ------------------------------------------ ... (case (list-index x ls) ((0) 'first) ((1) 'second) ((2) 'third) ((3 4) 'higher) (else 'too-high)) Q: What's this like in C/C++? In Pascal? this is like switch, pascal's case Q: What's different about this from the C/C++ statement? it's an expression no "break" needed ==> avoids a common error This was invented by Tony Hoare, Pascal is the first language to have this feature. Has very fast implementation: indirect branch through jump table based on value ------------------------------------------ SYNTAX ::= ( case {}+ ) ::= ( ) ::= ( {}+ ) ::= | | ::= ( else ) ::= SEMANTICS (let ((*key* e)) (case e (cond (kl1 b1) ((memv *key* 'kl1) b1) (kl2 b2) ((memv *key* 'kl2) b2) ... ... (kln bn) ((memv *key* 'kl3) b3) (else be)) (else be))) ------------------------------------------ if time: Q: can you do exercises 3.3.3 and 3.3.4?