Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Combinatory logic wikipedia , lookup
Lambda calculus definition wikipedia , lookup
Closure (computer programming) wikipedia , lookup
Lambda calculus wikipedia , lookup
Falcon (programming language) wikipedia , lookup
Anonymous function wikipedia , lookup
Lambda lifting wikipedia , lookup
Common Lisp wikipedia , lookup
COS220 Concepts of PLs AUBG, COS dept Lecture 52 Programming Styles (Functional Programming) Reference: R.Sebesta, Chapter 15 5/1/2017 Assoc. Prof. Stoyan Bonev 1 Introduction to FP Imperative programming vs. functional programming Language applied to functional programming is LISP – LISt Programming. It was invented to provide language features for list processing, the need for which grew out of the first application in the area of AI, expert systems, knowledge based systems. LISP – J.McCarthy, MIT, 1958 Lisp has two main descendants: Scheme–Sussman, MIT, 1975; Common Lisp, 1984 Related languages: ML, LCF, Miranda, Haskell 5/1/2017 Assoc. Prof. Stoyan Bonev 2 Lisp source illustrated A function call is written as a list with the function name or operator's name first, and the arguments following: Imperative style Functional style f(x, y, z); 5/1/2017 Assoc. Prof. Stoyan Bonev 3 Lisp source illustrated A function call is written as a list with the function name or operator's name first, and the arguments following: Imperative style Functional style f(x, y, z); (f 5/1/2017 x y Assoc. Prof. Stoyan Bonev z) 4 Lisp source illustrated A function call is written as a list with the function name or operator's name first, and the arguments following: Imperative style Functional style f(x, y, z); (f x y z) sqrt(a); 5/1/2017 Assoc. Prof. Stoyan Bonev 5 Lisp source illustrated A function call is written as a list with the function name or operator's name first, and the arguments following: Imperative style Functional style f(x, y, z); (f sqrt(a); (sqrt 5/1/2017 x y z) a) Assoc. Prof. Stoyan Bonev 6 Lisp source illustrated A function call is written as a list with the function name or operator's name first, and the arguments following: Imperative style Functional style f(x, y, z); (f sqrt(a); (sqrt x y z) a) 10 + 20 5/1/2017 Assoc. Prof. Stoyan Bonev 7 Lisp source illustrated A function call is written as a list with the function name or operator's name first, and the arguments following: Imperative style Functional style f(x, y, z); (f sqrt(a); (sqrt 10 + 20 (+ 5/1/2017 x y z) a) 10 Assoc. Prof. Stoyan Bonev 20) 8 Lisp source illustrated A function call is written as a list with the function name or operator's name first, and the arguments following: Imperative style Functional style f(x, y, z); (f sqrt(a); (sqrt 10 + 20 (+ x y z) a) 10 20) gcd(a+b, c*d*e); 5/1/2017 Assoc. Prof. Stoyan Bonev 9 Lisp source illustrated A function call is written as a list with the function name or operator's name first, and the arguments following: Imperative style Functional style f(x, y, z); (f sqrt(a); (sqrt 10 + 20 (+ gcd(a+b, c*d*e); (gcd (+ a b) (* c d 5/1/2017 x y z) a) 10 Assoc. Prof. Stoyan Bonev 20) e)) 10 What is FP? FP is a specific programming style in which: 1/ to write a functional program means to define a function or a set of functions; 2/ the only activity performed at run time is the function call statement. Pure FP is a programming style with - no memory allocation; - no assignment statements; - no loops, no iterative statements; - no flow charts; - no imperative (procedure) algorithms. 5/1/2017 Assoc. Prof. Stoyan Bonev 11 Corner stones to evaluate FP • λ-calculus (after A. Church) • The LISP PL (invented by J.McCarthy) • John Backus and his paper “Can Programming be Liberated from the von Neumann Style? A Functional Style and its Algebra of Programs.”, Com of the ACM, vol21, no8, pp613-641 5/1/2017 Assoc. Prof. Stoyan Bonev 12 Functional Programming COMPOSITION OF FUNCTIONS = PROGRAMS 5/1/2017 Assoc. Prof. Stoyan Bonev 13 Basic principles of FP Successful Functional Programming needs: • a fixed set of base, primitive, standard, generic functions; • a mechanism to build new more powerful functions using formerly defined functions or base set of available functions. 5/1/2017 Assoc. Prof. Stoyan Bonev 14 Examples Given a base set function: max(x,y) Task1: compose a function that returns the greatest among three arguments greatest(a,b,c) max(a, max(b,c)) max(max(a,b), c) max(b, max(a,c)) 5/1/2017 Assoc. Prof. Stoyan Bonev 15 Examples Given a base set function: max(x,y), greatest(x,y,z) Task2: compose a function that returns the greatest among six arguments max(greatest(a,b,c), greatest(d,e,f)) greatest(max(a,b), max(c,d), max(e,f)) 5/1/2017 Assoc. Prof. Stoyan Bonev 16 So, for FP we need: 1/ base set of functions; 2/ mechanism for function composition; 3/ nothing else. Requirements to the base set of functions: - effective machine implementation; - to be easy for use. 5/1/2017 Assoc. Prof. Stoyan Bonev 17 So, for FP we need: For example, the base set should include functions for arithmetic operators, like add(x,y) x + y sub(x,y) x - y mul(x,y) x * y div(x,y) x / y Using these four functions, it’s possible an arbitrary expression to present in functional notation a+b*c (2*x + 3*y) / (x-4) 5/1/2017 Assoc. Prof. Stoyan Bonev 18 So, for FP we need: add(x,y) x + y mul(x,y) x * y a+b*c sub(x,y) x - y div(x,y) x / y is to be transformed to add(a, mul(b,c) ) 5/1/2017 Assoc. Prof. Stoyan Bonev 19 So, for FP we need: add(x,y) x + y mul(x,y) x * y sub(x,y) x - y div(x,y) x / y (2*x + 3*y) / (x-4) is to be transformed to div( add( mul(2,x), mul(3,y)) , sub(x,4) ) 5/1/2017 Assoc. Prof. Stoyan Bonev 20 Intro to LISP and its dialects Intro to LISP and its dialects Before we comment LISP syntax (S-expressions, atoms, base set of functions) we’ll remind the List data structure. List is a basic data structure. It is the only data structure available in LISP to describe, present and store program code and data. Pure LISP data structures: atoms and lists: • Atoms are symbols that have the form of identifiers or numeric constants; • Lists are specified by surrounding/delimiting their elements within parentheses. 5/1/2017 Assoc. Prof. Stoyan Bonev 22 Lists Simple lists, in which elements are restricted to be only atoms, have the form ( A B C D ) Nested list structures are specified same way (A(BC) D (E (FG))) The internal representation may be illustrated on the white board. 5/1/2017 Assoc. Prof. Stoyan Bonev 23 LISP syntax-model of simplicity Program code and Program data in Lisp have exactly the same form: parenthesized list. Consider the list: ( A B C D ) • When interpreted as data, it is a list of four elements (data items). • When viewed as code, it is the application of function named A to its three arguments B, C, and D. 5/1/2017 Assoc. Prof. Stoyan Bonev 24 The LISP machine infinite loop The LISP machine infinite loop Most popular LISP machines (Scheme, Clisp) are implemented as an interpreter that operates as infinite loop performing the following three actions: Read-Eval-Print Loop or REPL Read; Evaluate; Write. Shortly the Lisp machine repeatedly: 1/ reads an expression typed by the user as a list except literals and names. 2/ interprets (evaluates) the expression. 3/ displays the resulting value. 5/1/2017 Assoc. Prof. Stoyan Bonev 26 Dialog using the LISP machine A/ input – numeric literal =>312 cr 312 5/1/2017 Assoc. Prof. Stoyan Bonev 27 Dialog using the LISP machine A/ input – numeric literal =>312 cr 312 B/ input – expression as a call to primitive functions in a list form. Expressions presented in prefix notation called Cambridge Polish notation Example: Ask the Lisp machine to calculate infix expression 220+370 or in other words to evaluate the expression =>(+ 220 370 ) 590 5/1/2017 Assoc. Prof. Stoyan Bonev 28 Dialog using the LISP machine A/ input – numeric literal =>312 cr 312 B/ input – expression as a call to primitive functions in a list form. Expressions presented in prefix notation called Cambridge Polish notation =>(+ 220 370 ) 590 =>(- 90 64 ) 26 5/1/2017 Assoc. Prof. Stoyan Bonev 29 Dialog using the LISP machine A/ input – numeric literal =>312 cr 312 B/ input – expression as a call to primitive functions in a list form. Expressions presented in prefix notation called Cambridge Polish notation =>(+ 220 370 ) 590 =>(- 90 64 ) 26 =>(* 25 8 ) 200 5/1/2017 Assoc. Prof. Stoyan Bonev 30 Dialog using the LISP machine A/ input – numeric literal =>312 cr 312 B/ input – expression as a call to primitive functions in a list form. Expressions presented in prefix notation called Cambridge Polish notation =>(+ 220 370 ) 590 =>(- 90 64 ) 26 =>(* 25 8 ) 200 =>(/ 10 2 ) 5 5/1/2017 Assoc. Prof. Stoyan Bonev 31 Combination List prefix notations like the examples just covered are called combination(s). The leftmost list element is the operator. The rest list elements are the operands. Two advantages of using such a notation: • It permits to describe procedures with an arbitrary number of arguments (operands). =>(+ 22 44) =>(+ 3 5 7) =>(+ 11 22 33 44) 66 15 110 • It permits to embed combinations as arguments. =>(+ (* 3 5 ) (- 10 6) ) 19 No restrictions on the level of embedding. 5/1/2017 Assoc. Prof. Stoyan Bonev 32 Using names in FP • Imperative programming: Names are specified using statements to define, declare, initialize, and assign values to variables. • FP: Names are specified using special form of a base function. In Scheme it is named define. In Clisp it is named setq. =>(define size 12) size It is said, that name size is bound to value of 12. In general, in its simplest form define serves to bind a symbol to the value of an expression. ( define symbol expression ) 5/1/2017 Assoc. Prof. Stoyan Bonev 33 More examples =>( define size 2 ) size 5/1/2017 Assoc. Prof. Stoyan Bonev 34 More examples =>( define size 2 ) size =>( define pi 3.1415 ) pi 5/1/2017 Assoc. Prof. Stoyan Bonev 35 More examples =>( define size 2 ) size =>( define pi 3.1415 ) pi =>( define two_pi ( * 2 pi ) ) two_pi 5/1/2017 Assoc. Prof. Stoyan Bonev 36 More examples =>( define size =>( define pi =>( define two_pi =>( define rad 5/1/2017 size 2 ) pi 3.1415 ) two_pi ( * 2 pi ) ) rad 10 ) Assoc. Prof. Stoyan Bonev 37 More examples =>( define size 2 ) size =>( define pi 3.1415 ) pi =>( define two_pi ( * 2 pi ) ) two_pi =>( define rad 10 ) rad =>( * 5 size ) 10 5/1/2017 Assoc. Prof. Stoyan Bonev 38 More examples =>( define size 2 ) size =>( define pi 3.1415 ) pi =>( define two_pi ( * 2 pi ) ) two_pi =>( define rad 10 ) rad =>( * 5 size ) 10 =>( * pi ( * rad rad ) ) 314.15 5/1/2017 Assoc. Prof. Stoyan Bonev 39 More examples =>( define size 2 ) size =>( define pi 3.1415 ) pi =>( define two_pi ( * 2 pi ) ) two_pi =>( define rad 10 ) rad =>( * 5 size ) 10 =>( * pi ( * rad rad ) ) 314.15 =>( * pi ( * size rad ) ) 62.83 5/1/2017 Assoc. Prof. Stoyan Bonev 40 More examples (cont.) =>( define circlearea ( * pi rad rad ) ) circlearea 5/1/2017 Assoc. Prof. Stoyan Bonev 41 More examples (cont.) =>( define circlearea ( * pi rad rad ) ) circlearea =>circlearea 314.15 5/1/2017 Assoc. Prof. Stoyan Bonev 42 More examples (cont.) =>( define circlearea ( * pi rad rad ) ) circlearea =>circlearea 314.15 =>( define circlelen ( * two_pi rad ) ) circlelen 5/1/2017 Assoc. Prof. Stoyan Bonev 43 More examples (cont.) =>( define circlearea ( * pi rad rad ) ) circlearea =>circlearea 314.15 =>( define circlelen ( * two_pi rad ) ) circlelen =>circlelen 62.83 5/1/2017 Assoc. Prof. Stoyan Bonev 44 Functions for constructing functions In Scheme User defined functions are described using the same base primitive function define. In this form define takes two lists as parameters. The first is the prototype of a function call with the function name followed by formal parameters, all in a list. The second list is the expression to which the name is to be bound. ( define ( <function_name> <parameters> ) <body> ) <parameters> are separated by space(s), not by comma(s) and the <body> is a sequence of expressions, all presented in form of lists. 5/1/2017 Assoc. Prof. Stoyan Bonev 45 Functions for constructing functions In Clisp User defined functions are described using the base primitive function defun. In this form defun precedes the function name and two lists. The first list includes the function parameters. The second list is the expression to which the name is to be bound. ( defun <function_name> ( <parameters> ) <body> ) <parameters> are separated by space(s), not by comma(s) and the <body> is a sequence of expressions, all presented in form of lists. 5/1/2017 Assoc. Prof. Stoyan Bonev 46 Examples ( define ( <function_name> <parameters> ) <body> ) ( define ( sqr x ) (* x x) ) ( define ( cube x ) (* x x x) ) ( define ( reciproc x ) (/ 1 x) ) 5/1/2017 Assoc. Prof. Stoyan Bonev 47 Using the functions defined • Explicit call for expression calculation =>(sqr 15) 225 5/1/2017 =>(sqr 21) 441 Assoc. Prof. Stoyan Bonev =>(sqr (sqr 3)) 81 48 Using the functions defined • Explicit call for expression calculation =>(sqr 15) 225 =>(sqr 21) 441 =>(sqr (sqr 3)) 81 • New functions definition =>(define (sum_of_squares x y) (+ (* x x) (* y y ) ) ) sum_of_squares 5/1/2017 Assoc. Prof. Stoyan Bonev 49 Using the functions defined • Explicit call for expression calculation =>(sqr 15) 225 =>(sqr 21) 441 =>(sqr (sqr 3)) 81 • New functions definition =>(define (sum_of_squares x y) (+ (* x x) (* y y ) ) ) sum_of_squares =>(sum_of_squares 3 4 ) 25 5/1/2017 Assoc. Prof. Stoyan Bonev 50 Using the functions defined • Explicit call for expression calculation =>(sqr 15) 225 =>(sqr 21) 441 =>(sqr (sqr 3)) 81 • New functions definition =>(define (sum_of_squares x y) (+ (* x x) (* y y ) ) ) sum_of_squares =>(sum_of_squares 3 4 ) 25 =>(define ( f a ) (sum_of_squares (+ a 1) (* a 2 ) ) ) f 5/1/2017 Assoc. Prof. Stoyan Bonev 51 Using the functions defined • Explicit call for expression calculation =>(sqr 15) 225 =>(sqr 21) 441 =>(sqr (sqr 3)) 81 • New functions definition =>(define (sum_of_squares x y) (+ (* x x) (* y y ) ) ) sum_of_squares =>(sum_of_squares 3 4 ) 25 =>(define ( f a ) (sum_of_squares (+ a 1) (* a 2 ) ) ) f =>(f 5) 136 5/1/2017 Assoc. Prof. Stoyan Bonev 52 Control flow The computational power of user defined functions may increase if we introduce a control flow mechanism instead providing function calls for linear algorithms. Let me remind the McCarthy’s conditional expression [b1->e1,b2->e2, … bn-1->en-1,en] and its LISP notation in three versions 5/1/2017 Assoc. Prof. Stoyan Bonev 53 First version ( cond ( <b1> ( <b2> ( <bn-1> ( <bn> <e1> ) <e2> ) ... <en-1> ) <en> ) ) 5/1/2017 Assoc. Prof. Stoyan Bonev 54 Second version ( cond ( <b1> ( <b2> ( <bn-1> ( else <e1> ) <e2> ) ... <en-1> ) <en> ) ) 5/1/2017 Assoc. Prof. Stoyan Bonev 55 Third version ( if <predicate> <then-expression> <else-expression> ) 5/1/2017 Assoc. Prof. Stoyan Bonev 56 Using conditional expressions To define function abs(x) = x, if = 0, if = -x, if ( define ( abs x ) ( cond ( (> x 0 ) x ) ( (= x 0 ) 0 ) ( (< x 0 ) ( - x) ) ) 5/1/2017 Assoc. Prof. Stoyan Bonev x>0 x=0 x<0 ) 57 Two more versions ( define ( abs x ) ( cond ( (< x 0 ) ( - x) ) ( else x) ) ) 5/1/2017 Assoc. Prof. Stoyan Bonev 58 Two more versions ( define ( abs x ) ( cond ( (< x 0 ) ( - x) ) ( else x) ) ) ( define ( abs x ) ( if (< x 0) ) 5/1/2017 (- x) x ) Assoc. Prof. Stoyan Bonev 59 Logical expressions Example 1: 5 < x < 10 5/1/2017 Assoc. Prof. Stoyan Bonev 60 Logical expressions Example 1: 5 < x < 10 (and (> x 5) (< x 10) ) 5/1/2017 Assoc. Prof. Stoyan Bonev 61 Logical expressions Example 2: define own predicate >= (define (>= x y ) (or (> x y) (= x y) ) ) OR (define (>= x y ) (not (< x y) ) ) 5/1/2017 Assoc. Prof. Stoyan Bonev 62 Recursion in LISP Function returns sum of n natural numbers Imperative (C/C++) version: int sumr(int n){ if (n==0) return n; else return n + sumr(n-1); } Functional Lisp list version: (define (sumr n) ( if (= n 0) 0 (+ n (sumr (- n 1) ) ) ) ) 5/1/2017 Assoc. Prof. Stoyan Bonev 63 List Processing in LISP LISP syntax • To specify a list: – ( A B C D ) function call A(B,C,D) – ‘( A B C D ) list of four data elements • 5/1/2017 To bind a name to a list ( define lis ‘(A B C D )) ( setq lis ‘(A B C D )) Assoc. Prof. Stoyan Bonev 65 Primitive list selectors • • List selector car. car returns the first element (head) of a list (car ‘(A B C D )) (car ‘((A B) C D)) (car ‘A) (car ‘(A)) 5/1/2017 returns A returns (A B) is an error returns A Assoc. Prof. Stoyan Bonev 66 Primitive list selectors • • List selector cdr. cdr returns the remainder of a list after its car is removed (cdr ‘(A B C D )) (cdr ‘((A B) C D)) (cdr ‘A) (cdr ‘(A)) 5/1/2017 returns (B C D) returns (C D) is an error returns ( ) – empty list Assoc. Prof. Stoyan Bonev 67 Primitive list constructor • • List constructor cons. cons builds a list using its two parameters (cons ‘A ‘() ) (cons ‘A ‘(B C) ) (cons (car lis) (cdr lis) ) 5/1/2017 returns (A) returns (A B C) returns lis Assoc. Prof. Stoyan Bonev 68 Primitive list predicates • null(<argument>) – • Returns T (true) if argument is an empty list atom(<argument>) – • Returns T (true) if argument is an atom eq(<argument> <argument>) – 5/1/2017 Returns T (true) if both arguments are the same, otherwise NIL (false) Assoc. Prof. Stoyan Bonev 69 Definition of functions on lists • Function to return the length of a list ( define (len x) (if (null x) 0 (+ 1 (len (cdr x) ) ) ) ) 5/1/2017 Assoc. Prof. Stoyan Bonev 70 Definition of functions on lists • Function to return the length of a list ( defun len (x) (if (null x) 0 (+ 1 (len (cdr x) ) ) ) ) 5/1/2017 Assoc. Prof. Stoyan Bonev 71 Definition of functions on lists • Function to return the length of a list ( setq lis ‘(A B C D) ) • Function call ( len lis ) 5/1/2017 returns 4 Assoc. Prof. Stoyan Bonev 72 Thank You For Your Attention