* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Structure of Programming Languages – Lecture 6
Survey
Document related concepts
Lisp (programming language) wikipedia , lookup
Curry–Howard correspondence wikipedia , lookup
Scala (programming language) wikipedia , lookup
Common Lisp wikipedia , lookup
Combinatory logic wikipedia , lookup
Intuitionistic type theory wikipedia , lookup
Lambda calculus wikipedia , lookup
Closure (computer programming) wikipedia , lookup
Anonymous function wikipedia , lookup
Lambda calculus definition wikipedia , lookup
Lambda lifting wikipedia , lookup
Falcon (programming language) wikipedia , lookup
Transcript
Structure of Programming Languages – Lecture 6 CSCI 6636 – 4536 October 20, 2014 CSCI 6636 – 4536 Lecture 6. . . 1/41 October 20, 2014 1 / 41 Outline 1 Names and Objects One object–one name? Symbols and Symbol Tables 2 Functional Programming Functional Programming Overview of Syntax Scheme Types Special Forms Scheme Functions 3 Defining gcd in Scheme 4 Higher-order Functions. 5 Homework CSCI 6636 – 4536 Lecture 6. . . 2/41 October 20, 2014 2 / 41 Names and Objects Names and Objects A many:many relationship Binding a name to an object Lifetimes CSCI 6636 – 4536 Lecture 6. . . 3/41 October 20, 2014 3 / 41 Names and Objects One object–one name? Names and Objects: A many:many relationship In an simple world, each object might have one name, and each name one object. Programming languages are far from simple. (Examples are given in the context of C.) An object can have NO name (the result of a call on malloc). An object can have one name: a local integer variable. An object can have two names: an array has a name, and when passed as a parameter, the parameter name becomes a synonym. A name can be bound to NO objects (#define UNIX) A name can be bound to exactly one object: a global variable name that is not redeclared elsewhere in the program. A name can be bound to multiple objects simultaneously: a parameter name in a recursive function, after several recursions. CSCI 6636 – 4536 Lecture 6. . . 4/41 October 20, 2014 4 / 41 Names and Objects One object–one name? Ambiguous Names There are several good reasons why the same program might have two definitions of the same name with different meanings: In OO languages, there are often many methods for the same function, with different signatures. In a multi-person team project, programmers working separately will be likely to use names in conflicting ways. When you import a package written by others, you will probably find that you have used some of the same identifiers. Programmers often reuse their own names. It is undesirable to invent a new name every variable in a large program. For all of these reasons, a useful language must allow the same name to have multiple meanings, and must provide a way to resolve ambiguities. CSCI 6636 – 4536 Lecture 6. . . 5/41 October 20, 2014 5 / 41 Names and Objects One object–one name? Resolving Ambiguous Names Ambiguous names are resolved in various ways in different languages: Use block-structured scoping and local names. Use the run-time stack to resolve recursive names. Apply default rules about the meaning of a name in an ambiguous context. Use a prefix (namespace name, package name, or class name) before the name of an object. Use the static modifier in C or a package in Java to restrict the scope of a name to its defining module. Define namespaces to keep each major package separate from others. A class encloses all functions and data related to it. CSCI 6636 – 4536 Lecture 6. . . 6/41 October 20, 2014 6 / 41 Names and Objects One object–one name? How much do names matter? Style matters. What does this simple C function do? typedef struct XX { char next; struct XX* prior; } myType; typedef myType* xType; xType storeIt (xType temp, char jxq) { xType jqx, first; first = temp; jqx = temp->prior; while (jqx != NULL) { if( jqx->next == jxq) jqx = NULL; else { first = jqx; jqx = jqx->prior; } } return first; } CSCI 6636 – 4536 Lecture 6. . . 7/41 October 20, 2014 7 / 41 Names and Objects Symbols and Symbol Tables Names and Objects Common to all languages is that an object has a name a type a body or meaning How these things are related, however, varies greatly. There are three major approaches: Static typing: C, FORTH, Dynamic typing: Scheme, scripting languages OO typing: C++, Java CSCI 6636 – 4536 Lecture 6. . . 8/41 October 20, 2014 8 / 41 Names and Objects Symbols and Symbol Tables Static Typing An object is created by a declaration or by calling new. Space is allocated for it according to the specified type and it may be initialized. The name, type, and memory location are recorded in the symbol table at compile time. This information may be supplied to a debugger. At run time, the name and type no longer exist. Names have been translated into positive and negative offsets from the stack pointer. Types have been checked and discarded. Symbol Table type name Runtime Memory binding storage object double weight int[4] CSCI 6636 – 4536 ages Lecture 6. . . 9/41 October 20, 2014 9 / 41 Names and Objects Symbols and Symbol Tables Dynamic Typing Objects are created by writing literals, by taking input, or by explicit calls on constructors. Names (global or local) are bound to these objects at run time by executing a binding command. The type of the object is part of the object at run time and is used by primitive functions for type checking. A name can be rebound at any time to a different object of possibly a different type. Symbol Table name Runtime Memory binding storage object : type tag weight 32.5 mylist CSCI 6636 – 4536 : list 17 Lecture 6. . . : real 10/41 October 20, 2014 10 / 41 Names and Objects Symbols and Symbol Tables OO Typing This is a mixture of the two simpler typing mechanisms: An object is created by a declaration or by calling new. Space is allocated and initialized according to the specified type. The name, type, and memory location are recorded in the symbol table at compile time and possibly supplied to a debugger. An object has a declared type and also inherits the type(s) of its base class(es). If the class is polymorphic, every instance will carry its type tag at run time and function methods will be dispatched based on that type tag. Symbol Table Pet Cat Bird CSCI 6636 – 4536 type name double Cat Pet* weight c1 pp Runtime Memory binding most objects Lecture 6. . . polymorphic objects 137 Cat 11/41 Callie F 10 October 20, 2014 11 / 41 Names and Objects Symbols and Symbol Tables Implications of the Typing System With static typing, many errors are caught at compile time, when the programmer is actively working on the project and best able to clarify his semantic intent. This is certainly the easiest and most sure way to catch a broad class of program errors. With dynamic typing, type errors are not caught until run time. This problem is ameliorated by using automated testing during the development process. The programmer writes his code and also writes a separate unit-test program to test each part of the code. Random tests are generated and their results compared to the expected results. Of course, automated testing could (should?) also be used with statically typed languages, but then it is a secondary defense, not the only defense. OO typing achieves the run-time flexibility of dynamic typing while maintaining the advantage of static type checking for most objects. CSCI 6636 – 4536 Lecture 6. . . 12/41 October 20, 2014 12 / 41 Functional Programming Hello Scheme! Functional Programming Introduction to Scheme CSCI 6636 – 4536 Lecture 6. . . 13/41 October 20, 2014 13 / 41 Functional Programming Functional Programming LISP, Scheme, and Functional Languages The Functional idea: no sequences, no assignment. LISP: early 1960’s: List processing language. Small and simple, but powerful Scheme: A lexically-scoped LISP. 1 Common Lisp: A collection of all the parts people have ever attached to a LISP system, including non-functional loops, assignments, and sequences. Miranda, ML, Haskell: Updated in both syntax (all those parentheses) and semantics (tuples). More purely functional than Common Lisp and Scheme. 1 Current versions of Scheme support a vector type. like a C array, its elements can be both read and written. In this class, we will work within the pure functional part of Scheme – that is, we will not use vectors. CSCI 6636 – 4536 Lecture 6. . . 14/41 October 20, 2014 14 / 41 Functional Programming Functional Programming The Scheme Language SLIB portable libraries Parsing Formatted I/O (stdio),printing Bit-Twiddling Arguments, getopt Time and date HTML Forms, Tables, parsing XML Arithmetic: modular, irrational Prime and random numbers Matrix algebra Fourier transform Graphing, solid modeling Color Database Arrays Sorting & Searching more ... 6. A Scheme System 5. Files, Folders, Devices 4. Lexical Structure, Comments 3. Syntax 2. Semantic Interpretation 1. Scheme Interpreter OR .. native code compiler Operating System and Hardware Platform CSCI 6636 – 4536 Lecture 6. . . 15/41 October 20, 2014 15 / 41 Functional Programming Overview of Syntax Workspaces and Overview Like Forth and Python, a Scheme application consists of a set of function definitions in a workspace. Workspaces can be saved. In Scheme, everything is written in prefix notation. Fundamental syntactic elements are: Objects: symbols, literals, pairs, vectors, functions, ports, eof, and null. Expressions. Lists of expressions, enclosed in parentheses. Function definitions. Function calls. Special forms. CSCI 6636 – 4536 Lecture 6. . . 16/41 October 20, 2014 16 / 41 Functional Programming Overview of Syntax Lexical Structure Not case-sensitive Delimiters: ( ) and whitespace Comments start with ; and go to the end of the line. Strings are enclosed in "double quotes". Identifiers: May be any length Cannot begin with a digit May contain letters and digits. May contain ! $ % & * + - . / : < = > ? @ _ ~ ^ Numbers: 12345 CSCI 6636 – 4536 123.45 123.4e5 Lecture 6. . . 1/2 1+2i 17/41 0+-2i October 20, 2014 17 / 41 Functional Programming Scheme Types Objects and Types in Scheme Numbers: only the first type, below, is required. Integers, no maximum value, exact. Rational numbers, exact Real numbers, not exact, like double in the local C implementation. Complex numbers, not exact. Boolean: #f and #t Symbols: ’red ’green Pairs: records with two untyped fields, used to build list structures. Constructor is cons. Selectors are car and cdr. Characters: #\A Strings: as in C, ”Hello” Vectors: 1-D arrays of objects (heterogeneous) Procedures (functions) are objects. Ports and the eof-object. null: The empty list. CSCI 6636 – 4536 Lecture 6. . . 18/41 October 20, 2014 18 / 41 Functional Programming Scheme Types Types have Constructors, Selectors, Predicates, Literals Constructors are needed for non-atomic types: A pair or a list is constructed by using cons A procedure is constructed using define and lambda. Selectors are needed for non-atomic types. They are use for run-time type testing: The selectors for the first and second parts of a pair are: car and cdr. An element of a vector is selected using vector-ref and a 0-based subscript. Predicates exist for all types: null? , pair? , boolean?, string? , procedure? Literals are defined for all primitive types: null, (3 4) , #f and #t, #\A, "Hello" CSCI 6636 – 4536 Lecture 6. . . 19/41 October 20, 2014 19 / 41 Functional Programming Scheme Types Literals and Type-Testing On the left are Scheme expressions. Following the arrow is the result of each expression: (number? 12.2) ⇒ #t (symbol? ’yellow ) ⇒ #t #t ) ⇒ #t (boolean? (procedure? +) ⇒ #t (null? ’()) ⇒ #t (pair? (pair? ’(0 1)) ⇒ #t ’null) ⇒ #f (string? (pair? ’(1)) ⇒ #t (pair? ’(a b c)) ⇒ #t "Hello") ⇒ #t (char-upper-case? #\s) ⇒ #f (char-lower-case? #\s) ⇒ #t (char->integer #\A) ⇒ 65 CSCI 6636 – 4536 Lecture 6. . . 20/41 October 20, 2014 20 / 41 Functional Programming Scheme Types Type Conversions Note the difference between a type predicate and the corresponding type conversion: (char-upcase #\s) ⇒ #\S (char-downcase #\S) ⇒ #\s (integer->char 97) ⇒ #\a CSCI 6636 – 4536 Lecture 6. . . 21/41 October 20, 2014 21 / 41 Functional Programming Scheme Types List Structures Four ways to define a list of two lists. 1. Constant: (define s3 '((1 2 ) (4 7)) ) 2. Basic notation: (define s3 '((1 . (2 . ())) . ((4 . (7 . ())) . () ))) 3. Construct it: (define s3 (cons (cons 1 (cons 2 ()) ) (cons (cons 4 (cons 7 ()) )) )) 4. Use variables: (define a (list 1 2) ) (define b (list 4 7) ) (define s3 (list a b)) S3 1 CSCI 6636 – 4536 2 4 Lecture 6. . . 22/41 7 October 20, 2014 22 / 41 Functional Programming Special Forms Special Forms A special form is a syntactic representation of a semantic construct. Special forms are needed for semantics that cannot be implemented in the form of normal functions. In scheme, this includes: Control statements Definition forms. Two functions for which we need lazy evaluation. CSCI 6636 – 4536 Lecture 6. . . 23/41 October 20, 2014 23 / 41 Functional Programming Special Forms Strict vs. Lazy Evaluation In strict evaluation, all of the arguments to a function are evaluated before calling the function. Normally, in Scheme (as in C) strict evaluation is used for function calls. In lazy evaluation, the function is called with un-evaluated argument expressions. An argument expression is not evaluated until its result is needed. If not needed, it is not evaluated. Although not essential for programming, cleaner and more efficient programs can be built if lazy evaluation is used for logical-and and logical-or. In Scheme, as in C, these functions use lazy evaluation: and ; Used like a function name, but performs lazy evaluation. or ; Used like a function name, but performs lazy evaluation. CSCI 6636 – 4536 Lecture 6. . . 24/41 October 20, 2014 24 / 41 Functional Programming Special Forms Special Forms for Definitions (define <name> <expr>) ; introduce a global name (let (<name-value-pair-sequence>) <expr-sequence>) ; introduce local names, bound to values. (define (<name> <parameter-sequence>) <expr-sequence>) ; define a global name for a function (lambda (<param-list>) <expr-sequence>) ; a function (lambda <name> <expr-sequence>) ; a vararg function Note: Unless the capacity for defining new vararg functions is part of the semantic basis of a language, functions such as printf() cannot be defined. CSCI 6636 – 4536 Lecture 6. . . 25/41 October 20, 2014 25 / 41 Functional Programming Special Forms Special Forms for Control (if <test> <true-expr> <false-expr>) ; Like C and FORTH (cond <test> <true-expr> <false-expr>) ; Same as old LISP (begin <expr-sequence>) ; a block of statements Recursion: a function can call itself. Scheme supports other control structures, but they can be defined as ordinary functions. CSCI 6636 – 4536 Lecture 6. . . 26/41 October 20, 2014 26 / 41 Functional Programming Scheme Functions Example: Procedure Definitions and Calls Function application (function call): (fname par1 par2...) (+ 3 5) (sqrt 25) (* 2 5 7) (char->integer #\A) lambda: a nameless function-object, with parameters. (lambda (x y) (+ (* x x) y)) define: bind a global name to an object. (define squarePlus (lambda (x y) (+ (* x x) y))) A short form of define for functions: (define (squarePlus x y) (+ (* x x) y)) Apply the nameless function to arguments 17 and 4. ((lambda (a b) (squarePlus (1+ b) a)) 17 4 ) Short and coherent form, using let. (let ( (a 17) (b 4) ) (squarePlus (1+ b) a) ) CSCI 6636 – 4536 Lecture 6. . . 27/41 October 20, 2014 27 / 41 Functional Programming Scheme Functions A statement sequence. A lambda expression allows a sequence of expressions in the body of the function. The value of the last expression is the return value. This is useful for output. (define run (lambda () (display "Countdown: ") (display (countdown 5)) (newline) () )) Here is the short form, without the explicit lambda: (define (run) (display "Countdown: ") (display (countdown 5)) (newline) () ) A sequence can also be defined with (begin ...) CSCI 6636 – 4536 Lecture 6. . . 28/41 October 20, 2014 28 / 41 Functional Programming Scheme Functions If and cond. The test-expression is followed by the true-part and the false-part. (define (factorial k) (if (= k 1) 1 (* k (factorial (- k 1)) ) ) ) Starting with the first pair, the expression on the left is evaluated. If #t, the expression on its right is evaluated and the answer becomes the value of the cond. Otherwise, control goes to the next test-pair. The last clause (which lacks a test) is the default clause. (define (score n) ; cond is a multi-branch conditional. (cond ((< n 0) "No!") ((= n 0) "Work harder.") ((= n 1) "Better.") ( "Nice.") ) ) CSCI 6636 – 4536 Lecture 6. . . 29/41 October 20, 2014 29 / 41 Functional Programming Scheme Functions Recurse rather than loop. ;;; Countdown from n to 0 (define (countdown k) (if (= k 0) ’(0) (cons k (countdown (- k 1)) ) ) ) (countdown 5) ⇒ (5 4 3 2 1 0) ;;; Do it with a tail recursion (same result). (define (counttail k s) (if (< k 0) (reverse s) (counttail (- k 1) (cons k s) ) ) ) CSCI 6636 – 4536 Lecture 6. . . 30/41 October 20, 2014 30 / 41 Defining gcd in Scheme gcd in Scheme We will use a subset of Scheme that is close to pure functional programming. Recursion, not loops. Binding, not assignment. Lexically scoped semantics. Our single escape from functional usage is that we will use sequences of statements. Please ask questions about Scheme. CSCI 6636 – 4536 Lecture 6. . . 31/41 October 20, 2014 31 / 41 Defining gcd in Scheme Part 2 Slide Slide Slide Slide Slide 33: 33: 34: 34: 35: run (The top-level function, like main.) loop (A tail-recursive function that implements repetition.) mygcd (Recursive definition using cond.) gcdprint (Produces formatted output.) The results of calling (run). CSCI 6636 – 4536 Lecture 6. . . 32/41 October 20, 2014 32 / 41 Defining gcd in Scheme Scheme implementation of GCD ;;; --------------------------------------------- Top-level (define (run) (display "Greatest Common Divisor") (newline) (loop) ) ;;; -------------------------------- Recurse rather than loop. (define (loop) (display "Enter two integers (0 0 to end): " ) (newline) (let ((n1 (read)) ; bind name to meaning. (n2 (read)) ; scope is the let-block. ) (cond ((= n1 0) ) ((gcdprint n1 n2) (loop))) )) CSCI 6636 – 4536 Lecture 6. . . 33/41 October 20, 2014 33 / 41 Defining gcd in Scheme Scheme implementation of GCD ;;; -------------------------------------- The gcd computation (define (mygcd x y) (cond ( (or (< x 0) (< y 0)) (mygcd (abs x) (abs y)) ) ((< x y) (mygcd y x) ) ((= y 0) x ) ( (mygcd y (remainder x y)) ) ) ) ;;; --------------------------------------------- Calling gcd (define (gcdprint a b) (let ( (f (list "The gcd of " a " and " b " is " (mygcd a b))) ) (for-each display f) (newline) ) ) CSCI 6636 – 4536 Lecture 6. . . 34/41 October 20, 2014 34 / 41 Defining gcd in Scheme Scheme implementation of GCD (run) ;;; ---------------------------------------- Calling gcd Greatest Common Divisor Enter two integers (0 0 to end): 21 98 The gcd of 98 and 21 is 7 Enter two integers (0 0 to end): 0 0 ;Value: #t CSCI 6636 – 4536 Lecture 6. . . 35/41 October 20, 2014 35 / 41 Higher-order Functions. Higher-order Functions. In Scheme, functions are first-class objects. That is, they can be used in the same ways and the same contexts as other objects such as numbers and lists. A higher-order function is one that takes a function as its parameter or returns a function as its result. Some of these are built into scheme, others can be defined. apply returns the result of applying its first argument to its second argument. map returns a list which is the result of applying its first argument to each element of its second argument. for-each is a built-in higher-order function. It maps a function down a list to cause side-effects, and is often used for I/O. A reduce operation applies a procedure to each element of a list. CSCI 6636 – 4536 Lecture 6. . . 36/41 October 20, 2014 36 / 41 Higher-order Functions. Higher-order Functions. for-each is a built-in higher-order function. It maps a function down a list to cause side-effects. It is often used for I/O. (define (gcdprint j k) (let ( (f (list "The gcd of " j " and " k " is " (gcd j k))) ) (for-each display f) (newline) #t ) ) 1 ]=> ( gcdprint 15 3) The gcd of 15 and 3 is 3 ;Value: #t CSCI 6636 – 4536 Lecture 6. . . 37/41 October 20, 2014 37 / 41 Higher-order Functions. Mapping down a List. map: Apply a function to a list, collect results, return. (map 1+ ’(1 3 7 15)) ⇒ (2 4 8 16) 1 ]=> (map 1+ ’(1 3 7 15)) ;Value 2: (2 4 8 16) 1 ]=> ( map square (list 17 15 13)) ;Value 12: (289 225 169) 1 ]=> (define (half x) (* x .5) ) 1 ]=> (define (half2 x) (/ x 2) ) 1 ]=> (map half (list 16 15 14)) ;Value 13: (8. 7.5 7.) 1 ]=> (map half2 (list 16 15 14)) ;Value 14: (8 15/2 7) CSCI 6636 – 4536 Lecture 6. . . 38/41 October 20, 2014 38 / 41 Higher-order Functions. Reduce A reduce operation applies a procedure to each element of a list. It calculates and returns a non-list answer. ::: proc is the function to apply ;;; base is an value for the null list. ;;; ls is the list to reduce. (define (reduce proc base ls) (if (null? ls) base (proc (car ls) (reduce proc base (cdr ls))) )) (reduce * 1 ’(2 3 4 5)) ⇒ 120 (reduce + 0 ’(2 3 4 5)) ⇒ 14 (reduce + 10 ’() ) ⇒ 10 CSCI 6636 – 4536 Lecture 6. . . 39/41 October 20, 2014 39 / 41 Higher-order Functions. Map-reduce (define (map-reduce f1 f2 base ls) (if (null? ls) base (f2 (f1 (car ls)) (map-reduce f1 f2 (define (odd x) (define (andy p (map-reduce odd (map-reduce odd CSCI 6636 – 4536 base (cdr ls))) )) (= 1 (modulo x 2)) ) q) (and p q)) andy #t ’(1 3 5 7 9)) ⇒ #t andy #t ’(1 3 4 5 7 9)) ⇒ #f Lecture 6. . . 40/41 October 20, 2014 40 / 41 Homework Homework: Read Chapters 6 and 7 1. Compare my implementations of gcd in Scheme and in Lisp. Identify the differences and comment on them. Run the scheme gcd program and turn in the evidence. 2. Give as regular expression, or set of them, that defines Scheme rational literals. 3. Draw a finite state machine that accepts Scheme real numbers. Assume that a number CAN to start or end with a decimal point and must have a decimal point somewhere in it. 4. What is a type tag? Explain in your own words why objects in Python and Scheme need type tags. 5. Write a function in Scheme to take as parameters the base and altitude of a right triangle. Print a formatted message that echoes the inputs and prints the area of the triangle. Use rational arithmetic. 6. Write a function in Scheme to take as parameters the diameter and height of a cylinder. Returns the volume of the cylinder. Use real arithmetic. CSCI 6636 – 4536 Lecture 6. . . 41/41 October 20, 2014 41 / 41