CSG 111 Lecture 01 Monday, January 7, 2008 / Wednesday, January 9, 2008 * Why take this class? * Why study Programming Languages? - Because you might need to implement one some day - (or something like a PL; a lot of data processing, when viewed through a particular lens, ends up having similar issues to interpreting a term in some odd language). - To better understand what distinquishes the various languages you encounter - Because it will make you a better programmer! - This is roughly analogous to how learning about the structure of the English language can make you a better English speaker, and moreover, learning about the structure of other languages other than your native tongue can improve your understanding of your native language * Overview of the class - Course policies - Course structure - Course syllabus * Programming Languages - for class Q: What are some examples of programming languages? - A[Monday]: - A[Wednesday]: - for class Q: Which ones of the above do you know and could write and run code using it, with reasonable confidence? - A[Monday]: - A[Wednesday]: - Q: How are Programming Languages different from Natural Languages? - Q: How are Programming Languages different from Data Description Languages, e.g. Markup Languages like HTML? * The big picture overview { pgm } Front-End => { syntax } => Interpreter => { answer } - (with potential for I/O with the interpreter) - and there are refinements - adding a compiler - subdividing the front-end into a scanner and parser * The Four Questions 1. What are the values in the language? - and what operations on those values are represented? - what are the expressed and the denoted values? - what are the types in the language? 2. What are the scoping rules of the language? - how are variables bound? How are they used? - what variables are in scope where? 3. What are the effects in the language? - are there side-effects at all? - can the world be affected by a program's effects? - can programs affect other programs? - can a program fail to terminate? - are there "non-local control effects" in the language? 4. What are the static properies of the language? - What can we predict about the behavior of a program w/o knowing the runtime values? - How can we analyze a program to predict this behavior? * A whirlwind introduction to Scheme, part I - Basic data types that most others have: - Numbers: 1 2 3 4 5 6 1/2 3/4 6/7 1.2 3.145196 - Strings: "hello there" "and hi again" - Functions that process values: + - string-append string->number - Can combine values by writing expressions > (+ 1 2) > (- 4 6) > (string-append "tee" "hee") > (string-append "fee" (string-append (string-append "fie" "foe") "fum")) > (string-append "fee" "fie" "foe" "fum") > (string->number "45") > (number->string 214) > (string->number (string-append (number->string 11) (number->string 5))) - If we want to name a constant value, rather than have to retype it at all of its uses, we use the define special form. Then we can just write the name as an expression to get that value > (define pi 3.141592653589793238) > pi > (define chant "Fee! Fie! Foe! Fum!") * Functions - Programming is the art of automation; the art of deciding what in a process (or expression) to keep constant and what to allow to vary. - Here are some strings: - "Dear Jack Tripper: You have been fired. Sincerely, Mgmt." - "Dear Janet Wood: You have been fired. Sincerely, Mgmt." - "Dear Larry Dallas: You have been fired. Sincerely, Mgmt." - It is a pain to write out three long strings. Plus, it seems likely that Mgmt might need to write this letter again. - By identifying which parts of the data are varying, and which parts remain constant, we can save ourself much effort. - Here is what function definitions look like in Scheme. ;; terminal-letter : String -> String ;; usage: (terminal-letter n) returns string to notify n that ;; he or she has been fired. (define terminal-letter (lambda (name) (string-append "Dear " name ": You have been fired." " Clean out your desk." " Sincerely, Mgmt."))) (terminal-letter "Jack Tripper") (terminal-letter "Janet Wood") (terminal-letter "Larry Dallas") - Functional abstraction isn't always about the physical effort we might spend typing. It can also be about reducing the mental effort associated with rederiving a relationship every time we want to use it. - Example: degrees and radians - Converting between these different units requires a couple of mathematical formulas that it might be worth codifying. ;; degrees->radians : Number -> Number ;; usage: (degrees->radians d) returns radians in an angle of d degrees. (define degrees->radians (lambda (d) (/ (* pi d) 180))) ;; radians->degrees : Number -> Number ;; usage: (radians->degrees r) returns degrees in an angle of r radians. (define radians->degrees (lambda (r) (/ (* 180 r) pi))) - Example of a complicated expression that you might recognize: - (-b + sqrt( b^2 - 4ac )) / 2a - (-b - sqrt( b^2 - 4ac )) / 2a - or rather, in scheme - (/ (+ (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a)) - (/ (- (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a)) * An introduction to Scheme, part II - Other atoms: Booleans, Symbols - Booleans: #t #f (< -1 2) (>= 3 4) - Symbols: 'twig 'stick (string->symbol "hello") - Data Definitions: ;; A Nat (short for natural number) is a non-negative integral Number. - cons, the minimalist data constructor - (cons val1 val2) produces the pair value (val1 . val2) - the unary function car pulls out the first value from the pair - the unary function cdr pulls out the second value from the pair > (car (cons 1 2)) 1 > (cdr (cons 1 2)) 2 > (cdr (cons (cons 1 2) (cons 3 4))) (3 . 4) > (cdr (car (cons (cons 1 2) (cons 3 4)))) 2 - Simple structures and data definition of structured data. ;; An NumPair is a (cons Num Num) * An introduction to Scheme, part III - case analysis - quadratic formula, discriminant identifies number of answers (3 cases) - four quadrants in the cartesian coordinate system (4 cases) - melting and evaporation points for H20 (3 cases) - responsibility of designer to choose cases that are mutually exclusive and collectively exhaustive - conditional expressions general form: (cond (TEST-1 EXP-1) (TEST-2 EXP-2) ...) specific examples: ;; count-quadratic-roots : Number Number Number -> Number ;; usage: (count-quadratic-roots a b c) counts roots of ax^2 + bx + c (define count-quadratic-roots (lambda (a b c) (cond ((< (- (* b b) (* 4 a c)) 0) 0) ((= (- (* b b) (* 4 a c)) 0) 1) ((> (- (* b b) (* 4 a c)) 0) 2)))) - data definition of unions ;; A StateOfMatter is one of: ;; - 'solid ;; - 'liquid ;; - 'gas ;; A MaybeNumber is one of: ;; - #f ;; - Number - The template (or skeleton) for processing such entities ;; fcn : StateOfMatter -> ??? (define fcn (lambda (som) (cond ((eq? som 'solid) ...) ((eq? som 'liquid) ...) ((eq? som 'gas) ...)))) ;; fcn2 : MaybeNumber -> ??? (define fcn2 (lambda (x) (cond ((boolean? x) ...) ((number? x) ...)))) * An introduction to Scheme, part IV - Representing unbounded structure - We saw how we kept adding on more and more pairs when we decided we might want more fields in our data structure. - But what do we do when we don't know how many things there might be in our structure? Are we stuck? - Recursive data definitions ;; A List-of-Nat (LoN for short) is one of: ;; - '() ;; - (cons Nat LoN) - Note the self-reference of LoN; this has implications for the code we write, *especially* for the skeletal code fragments that we put down first. - Examples of List-of-Nat: > '() () > (cons 2 '()) (2) > (cons 1 (cons 2 '())) (1 2) > (cons 16 (cons 1 (cons 2 '()))) (16 1 2) - Schemers often use Lists - So while in C/Java/etc you might start off thinking that you need an Array. They are not a tool we will be using often. ;; A Listof[X] is one of: ;; - '() ;; - (cons X Listof[X]) - The template (or skeleton) for processing such entities ;; fcn : Listof[X] -> ??? ;; usage: ??? (define fcn (lambda (l) (cond ((null? l) ...) (else ... (car l) ... (fcn (cdr l)) ...)))) ;; concat : Listof[String] -> String ;; usage: (concat (list s1 s2 ...)) returns concatenation of s1 s2 ... (define concat (lambda (l) (cond ((null? l) "") (else (string-append (car l) (concat (cdr l))))))) * Abstraction and how to interpret instances of data - A point (on the cartesian plane) has a x coordinate and a y coordinate. ;; An CartPt is a (cons Num Num) - Draw a graph, and explicitly draw the points (0 . 2) (2 . 3) (2 . 0) (4 . 1) (-1 . 3) (3 . -2) - Also, a point has a angle and distance from the origin ;; A PolarPt is a (cons Num Num) - But what does this mean about all the points I drew before? What point is (2 . 3) supposed to correspond to? - The issue here is that it is *not* *enough* in general to know how the data is structured. You might need a layer of interpretation of that data. ;; An CartPt is a (cons Num Num) ;; interpretation: The CartPt (x . y) is the point at the intersection ;; of the horizontal line through y on the y-axis and the vertical ;; line through x on the horizontal axis. ;; A PolarPt is a (cons Num Num) ;; interpretation: The PolarPt (r . t) is the point r units from the ;; origin along the line t degrees counterclockwise from the ;; horizontal axis. ;; So the point <0,2> can be represented as the CartPt (0 . 2) ;; can be represented as the PolarPt (2 . 90) ;; the point <3,4> can be roughly represented as the PolarPt (5 . 53) - Another example of how you sometimes need an interpretative layer: - A Multiset (or "bag") is like a mathematical set, except that in a Multiset, you keep track of the number of times an element occurs in the multiset. - But like a set (and unlike, say, a sequence), the elements in a multiset are not ordered. - So the multiset { 1, 2, 1, 3 } is indistinquishable from the multiset { 3, 1, 1, 2 } - But the multiset { 3, 1, 1, 2 } is different from the multiset { 3, 1, 2 } - If you wanted to represent Multisets of Natural numbers in Scheme code, you might choose to represent them using List-of-Nat. - A problem arises when an "overly clever" programmer decides to use the following representation and associated interpretation (which we will refer to as the "indices-as-bag-elements" interpretation) ;; A MultisetOfNat is a Listof[Nat] ;; interpretation: the list (x_0 y_1 z_2 ... k_n ...) ;; is the multiset with x occurrences of the nat 0 ;; y occurrences of the nat 1 ;; z occurrences of the nat 2 ;; and generally, k occurrences of the nat n. - Now, we have an odd situation, where some people would look at the list (1 3 0 1) and say "that must be the bag {0, 1, 1, 3}", (we will call such an interpretation the "values-as-bag-elements" interpretation, since it treats the values within the list as the contents of the multiset). - But in fact, according to the indices-as-bag-elements interpretation, the list (1 3 0 1) is the bag { 0, 1, 1, 1, 3 } (because it needs to have 1 zero, 3 ones, no twos, and 1 three). - Here is a table illustrating the different interpretations and their implications; starting from the representation in the middle, you can see how the same list data ends up representing very different multisets depending on which interpretation you employ. indices-as-bag-elements | list rep | values-as-bag-elements ---------------------------------------------------------------- { 1, 2, 3, 3, 3 } | (0 1 1 3) | { 0, 1, 1, 3 } | | { 0, 1, 1, 1, 3 } | (1 3 0 1) | { 0, 1, 1, 3 } | | { 0, 1, 1 } | (1 2) | { 1, 2 } | | { 0, 0, 1 } | (2 1) | { 1, 2 } - Another possible issue when designing a representation for a class of data is whether one chooses to further constrain what makes a valid representation by introducing a "representation invariant" - In our multiset example, a different program designer might choose to use the values-as-bag-elements interpretation, but also add a constraint that the list be sorted in ascending order: ;; A MultisetOfNat2 is a Listof[Nat] sorted in ascending order ;; interpretation: the list (x_0 y_1 z_2 ... k_n ...) ;; is the multiset { x_0, y_1, z_2, ..., k_n, ... } - This eliminates the (1 3 0 1) and (2 1) entries from the table above.