EECS 111 LECTURE 1 This Course =========== This course is about the fundamentals of programming (and computation): - from specification to implementation - software engineering principles - (a little bit of computation) This course is *not* about: - Racket, or any other language: Java, C, C++, Python, etc. We have to pick a language, or else this is just idle talk. We picked a teaching language inspired by Racket, but it *not* Racket. - Programming tools (DrRacket, gcc, gdb, javac, etc.) Again, we need something, so we picked DrRacket, but it is designed to stay out of the way as much as possible. - Specific libraries or protocols (http, XML, Gtk, etc.) We might see glimpses of these in exercises, but only as they help you understand those points above - How programs get translated to digital signals Programming digital computers, or programming with genes in test tubes---it doesn't matter. We don't study the details of that; we study how to construct and maintain the programs themselves. Arithmetic, Algebra, and Computation ==================================== Arithmetic is computing. What are do these equal: 2 + 3 = 5 4 x 2 = 8 cos(0) = 1 No one said: 2 + 3 = 1 + 4 or 2 + 3 = 1 + 1 + 3 even though those are valid, right? There is a direction to those equalities, complex to simple. So, we are simplifying those expressions, until nothing is left to do. We know how to simplify them based on the basic rules of arithmetic. *That*'s what computation is about, from an algebraic perspective. Simplification of expressions. How about this one?: (2 + 3) x 5 = 5 x 5 = 25 We simplify complex expressions by finding embedded, simpler ones to simplify. How about this one?: 2 + 3 x 5 = 2 + 15 = 17 Precedence rules help us find the next to simplify. How about definitions?: f(x) = x × (x + 1) Now we can use that defined function in expressions: f(2) = 2 × (2 + 1) = 2 × 3 = 6 Let's talk notation: - sometimes operators go in the middle: +, × - sometimes operators go in front: cos. - sometimes parens indicate grouping: 1 × (2 + 3) - sometimes parens are used for arguments: cos(0) - sometimes parens are optional: 1 + (2 × 3) - sometimes not: (1 + 2) × 3 - sometimes = means a definition: f(x) = x * x + 1 - sometimes = means a simplification step: 1 + 2 = 3 YUCK! - When we get to full blown computation, all this ambiguity and inconsistency gets incredibly unwieldy. Let's use a simpler notation: - operators go at the beginning followed by their arguments - all operations begin and end with matching parens - never add any extra parens! 1 + 2 --> (+ 1 2) 4 + 2 * 3 --> (+ 4 (* 2 3)) cos(0) + 1 --> (+ (cos 0) 1) Let's simplify definitions in the same manner. We'll use a *keyword*: `define` f(x) = x * (x + 1) (define (f x) (* x (+ x 1))) syntax: `(`, `define`, "function call skeleton", body, `)` Now, this `f' becomes a new operator and we use our new syntax rules just as before: f(2) --> (f 2) f(1 + 3) --> (f (+ 1 3)) evaluation with the new notation is just like before (but with the new notation, of course): (f (+ 1 3)) = (f 4) = (* 4 (+ 4 1)) = (* 4 5) = 20 Not Just Numbers ---------------- Numbers are not the only kinds of values! What about truth values?: 1 < 2 = true (< 1 2) = #true 1 > 2 = false (> 1 2) = #false 2 >= 2 = true (>= 2 2) = #true In programming, truth values are called "Booleans". Anyone care to guess about `and` and `or`? What `not`? (not (= 1 2)) = (not #false) = #true We can also work with textual data, which in programming is usually called a "string": "apple" "pear" (string=? "apple" "pear") = false (string=? "pear" "pear") = true (string-append "apple" " or " "pear") = "apple or pear" DrRacket also supports *images* as values. We'll see this more next time, but here's a taste: (rectangle 35 35 "solid" "black") = ... a solid box ... (circle 25 "outline" "white") = ... an outline circle ... what about combining images? (overlay (rectangle 25 25 "solid" "white") (circle 35 "outline" "black")) = (overlay .. a solid box ... (circle 35 "outline" "black")) = (overlay ... ...) ;; draw pictures on board = ... How about a function? (define (anonymize img) (underlay img (circle (* 0.4 (image-width img)) "solid" "blue")))) What does that do? (anonymize ...me...) = ... me with dot ... The Stepper ----------- DrRacket can actually show you all the computation steps automatically instead of what we've been doing manually. Put everything in the definitions window, click Step, and watch it go. Programming ============ That was computation. What about programming? Where did `anonymize` come from? Did the programming goddess smile down on us and voila out it comes from our fingers? - Programming requires creativity Programming requires creativity, there's no doubt. But to guide and focus our creativity into programs, we also need structure and design rules. - Like music You need to understand scales, rhythm, harmony, and maybe even counterpoint (if for no other reason than to know how to move *beyond* those things) - So far, only notation. What we've seen so far is merely the notation. We need more than notation to get to beautiful music. - We need design recipes Like a plagal cadence, or sonata form. In this class, you'll learn recipes for programming. As you advance, we'll build upon a simple recipe that we start with today. Simplest Design Recipe overview: 1. Signature, purpose, header 2. Examples 3. Body 4. Tests Signature, purpose, and header: ; f2c : Number -> Number ; Finds Celsius equivalent of a Fahrenheit temperature. (define (f2c f) ...) ; is-milk? : String -> Boolean ; Determines whether `s` is "milk". (define (is-milk? s) ...) Examples: (These are sample inputs and outputs that ensure you know what you're doing. Write these *before* you write the body of the function.) (f2c 32) should be 0 (f2c 212) should be 100 (f2c -40) should be -40 (is-milk? "oj") should be #false (is-milk? "milk") should be #true Body: (This is where the creativity comes in. How do you get from the inputs to the outputs?) (define (f2c f) (* 9/5 (- f 32))) (define (is-milk? s) (string=? s "milk")) Tests: (Automated tests confirm that particular expressions evaluate to the values that we expect.) (check-expect (f2c 32) 0) (check-expect (f2c 212) 100) (check-expect (f2c -40) -40) (check-expect (is-milk? "oj") #false) (check-expect (is-milk? "milk") #true) (Often, if you're clever, you can write your examples below the function definition in the format above and all you need to do for the testing step is to click Run in DrRacket and check that your tests all pass. But sometimes there will be clearer ways to write your examples that won't work well as tests.) Importance of the Design Recipe ------------------------------- The design recipe is *the* critical thing I hope you will take away from this course. It is *not* Racket-specific. Yes, it is simple now, but if you don't get in the habit now, you'll fail later when you need it. Accordingly, if there's no design recipe visible in your code, it won't get a good grade.