Syntax and Semantics in Programming
280 likes | 301 Vues
This lecture covers syntax and semantics in programming, including examples and a substitution model. It explains the evaluation of expressions, IF statements, Lambda special form, and naming procedures. The lecture also delves into recursive algorithms and the importance of base cases.
Syntax and Semantics in Programming
E N D
Presentation Transcript
Lecture 2 מבוא מורחב
Review: syntax vs. semantics Syntax Semantics מבוא מורחב
==> (define score 23) ==> (* (+ 5 6 ) (- score (* 2 3 2 ))) * + 5 6 - 23 * 2 3 2 11 12 11 121 An example מבוא מורחב
Substitution model • To Apply a compound procedure to a list of arguments: • Replace the formal parameters with the corresponding actual values. • Evaluate the body of the procedure with these values. • (define square (lambda (x) (* x x))) • 1. (square 4) • 2. (* 4 4) • 3. 16 מבוא מורחב
Review: evaluation of an expression • To Evaluate a combination (other than special form) or a compound procedure • Evaluate all of the sub-expressions in any order • Apply the procedure that is the value of the leftmost sub-expression to the arguments (the values of the other sub-expressions) • The value of a numeral: number • The value of any name: the associated object in the environment • The value of a built-in operator: machine instructions to execute מבוא מורחב
IF special form (if <predicate> <consequent> <alternative>) (if (< 2 3) 2 3) ==> 2 (if (< 2 3) 2 (/ 1 0)) ==> ERROR 2 • If the value of <predicate> is #t, • Evaluate <consequent> and return it • Otherwise • Evaluate <alternative> and return it מבוא מורחב
IF is a special form • In a general form, we first evaluate all arguments and then apply the function • (if <predicate> <consequent> <alternative>)is different: <predicate> determines whether we evaluate <consequent> or <alternative>. We evaluate only one of them Can you see why it has to be that way? מבוא מורחב
Lambda special form • lambda syntax (lambda (x y) (+ x y x 2)) • 1st operand position: the parameter list(x y) • a list of names (perhaps empty) • determines the number of operands required • 2nd operand position: the body(+ x y x 2) • may be any expression • not evaluated when the lambda is evaluated • evaluated when the procedure is applied מבוא מורחב
Naming procedures • An application of an unnamed procedure: • ((lambda (x) (* x x)) 4) ==> 16 • 2. Naming the procedure: • (define square (lambda (x) (* x x))) • (square 3) 3. Syntactic Sugar: (define (square x) (* x x))
Some examples: • (define twice ) • (twice 2) ==> 4 (twice 3) ==> 6 • (define second ) • (second 2 15 3) ==> 15(second 34 -5 16) ==> -5 (lambda (x) (* 2 x)) (lambda (x y z) y) מבוא מורחב
An example for the substitution model (define square (lambda (x) (* x x)))(define average (lambda (x y) (/ (+ x y) 2))) (average 5 (square 3))(average 5 (* 3 3))(average 5 9) first evaluate operands,then substitute (applicative order) (/ (+ 5 9) 2)(/ 14 2) if operator is a primitive procedure, 7replace by result of operation מבוא מורחב
S(n-1) Sum of squares • S(n) = 02 + 12 + 22 ………. …… (n-1)2 + n2 • Notice that: • S(n) = S(n-1) + n2 • S(0) = 0 • These two properties completely define the function
An algorithm for sum of squares (define sum-squares (lambda (n) (if (= n 0) 0 (+ (sum-squares (- n 1)) (square n))))
Evaluating (sum-squares 3) (define (sum-squares n) (if (= n 0) 0 (+ (sum-squares (- n 1)) (square n)))) (sum-squares 3) (if (= 3 0) 0 (+ (sum-squares (- 3 1)) (square 3))) (+ (sum-squares (- 3 1)) (square 3)) (+ (sum-squares (- 3 1)) (* 3 3)) (+ (sum-squares(- 3 1)) 9) (+ (sum-squares 2) 9) (+ (if (= 2 0) 0 (+ (sum-squares (- 2 1)) (square 2))) 9) … (+ (+ (sum-squares 1) 4) 9) … (+ (+ (+ (sum-squares 0) 1) 4) 9) (+ (+ (+ (if (= 0 0) 0(+ (sum-squares (- 0 1)) (square 0))) 1) 4) 9) (+ (+ (+ 0 1) 4) 9) … 14 מבוא מורחב
How to design recursive algorithms • Show how to solve big instances, if you know the solution to • smaller instances. • Wishful thinking: if I could only solve the smaller instance … • Solve the “base cases”. For example, for sum of squares: S(n) = S(n-1) + n2 (induction rule) S(0)=0 (base case) מבוא מורחב
General form of recursive algorithms • test, base case, recursive case (define sum-sq (lambda (n) (if (= n 0) ; test for base case 0 ; base case (+ (sum-sq (- n 1)) (square n)) ; recursive case ))) • base case: non-decomposable problem • recursive case: larger (decomposable) problem מבוא מורחב
Evaluating (sum-squares 3) in the substitution model,with IF a regular form…. (sum-squares 3) (if (= 3 0) 0 (+ (sum-squares (- 3 1)) (square 3))) (if #f 0 (+ (sum-squares 2) 9)) (if #f 0 (+ (if #f 0 (+(sum-squares 1)4))) 9)) .. calling (sum-squares 0) …. calling (sum-squares -1) (define (sum-squares n) (if (= n 0) 0 (+ (sum-squares (- n 1)) (square n)))) We evaluate all operands. We always call (sum-squares) again. We get an infinite loop…….. OOPS מבוא מורחב
Another example of a recursive algorithm • even? (define even? (lambda (n) (not (even? (- n 1))) ; recursive case ))) • (if (= n 0) ; test for base case • #t ; base case מבוא מורחב
Short summary • Design a recursive algorithm by 1. Solving big instances using the solution to smaller instances. 2. Solving directly the base cases. • Recursive algorithms have 1. test 2. recursive case 3. base case מבוא מורחב
X = 2 G = 1 X/G = 2 G = ½ (1+ 2) = 1.5 X/G = 4/3 G = ½ (3/2 + 4/3) = 17/12 = 1.416666 X/G = 24/17 G = ½ (17/12 + 24/17) = 577/408 = 1.4142156 SQRT • To find an approximation of square root of x: • Make a guess G • Improve the guess by averaging G and x/G • Keep improving the guess until it is good enough מבוא מורחב
(define initial-guess 1.0) (define precision 0.0001) (define (sqrt-iter guess x) (if (good-enough? guess x) guess (sqrt-iter (improve guess x) x))) (define (good-enough? guess x) (< (abs (- (square guess) x)) precision)) (define (improve guess x) (average guess (/ x guess))) (define (sqrt x) (sqrt-iter initial-guess x)) מבוא מורחב
Good programming • 1. Divide the task to well-defined, natural, and • simple sub-tasks. • E.g: good-enough? and improve. • Thumb of rule: If you can easily name it, it does a well-defined task. 2. Use parameters. E.g.: precision, initial-guess. 3. Use meaningful names. מבוא מורחב
Procedural abstraction • It is better to: • Export only what is needed • Hide internal details. The procedure SQRT is of interest for the user. The procedure improve-guessis an internal detail. • Exporting only what is needed leads to: • A clear interface • Avoids confusion מבוא מורחב
Rewriting SQRT (Block structure) (define (sqrt x) (define (sqrt-iter guess x) (if (good-enough? guess x) guess (sqrt-iter (improve guess x) x))) (define (good-enough? guess x) (< (abs (- (square guess) x)) precision)) (define (improve guess x) (average guess (/ x guess))) (define initial-guess 1.0) (define precision 0.00001) (sqrt-iter initial-guess x)) מבוא מורחב
Lexical Scoping • Every variable is: • Recognized within the procedure where it is defined (its scope). • Not recognized outside it. • Allows different procedures to use the same variable name. E.g., different procedures can use the variable name i as a counter. • A variable can be used globally within its scope. No need to pass it from one procedure to another. מבוא מורחב
SQRT again, x is used globally. (define (sqrt x) (define (good-enough? guess) (< (abs (- (square guess) x)) precision)) (define (improve guess) (average guess (/ x guess))) (define (sqrt-iter guess) (if (good-enough? guess) guess (sqrt-iter (improve guess)))) (define initial-guess 1.0) (define precision 0.00001) (sqrt-iter initial-guess)) מבוא מורחב
Variables scope (define (sqrt x) (define (good-enough? guess) (< (abs (- (square guess) x)) precision)) (define (improve guess) (average guess (/ x guess))) (define (sqrt-iter guess) (if (good-enough? guess) guess (sqrt-iter (improve guess)))) (define initial-guess 1.0) (define precision 0.00001) (sqrt-iter initial-guess)) מבוא מורחב
Proc1.x Proc3.x An example (define (proc1 x) (define (proc2 y) (+ x y)) (define (proc3 x) (proc2 x)) (proc3 (* 2 x))) (proc1 4) proc1.x = 4 (proc3 8) proc3.x = 8 (proc2 8) proc2.y = 8 proc2.x=proc1.x=4 12 מבוא מורחב