# CSE 3341/655; Part 4 55 A functional program: Collection of functions A function just computes and returns a value No side-effects In fact: No program.

## Presentation on theme: "CSE 3341/655; Part 4 55 A functional program: Collection of functions A function just computes and returns a value No side-effects In fact: No program."— Presentation transcript:

CSE 3341/655; Part 4 55 A functional program: Collection of functions A function just computes and returns a value No side-effects In fact: No program variables whose values change! A function body: Mainly calls to other functions Languages: LISP, Scheme, ML, Haskell,... Functional Programming

CSE 3341/655; Part 4 56 Program just says what is needed, not how to compute it The “system” figures out the how DB systems are (sort of) logic programming systems Languages: Prolog Logic programming is not very popular except as DBs Logic Programming

CSE 3341/655; Part 4 57 Must provide: Suitable data types Set of primitive functions A notation for calling functions Way to construct new functions by composing existing ones in different ways Functional Languages (Chap. 10)

CSE 3341/655; Part 4 58 Data Types: Atomic and non-atomic S-expressions (“symbolic exps.”) Atoms: Numbers (we use only integers) Strings: “xyz”, “34” etc. Symbols (i.e., identifiers): XYZ, AB12, + etc. Some important symbols: #t (denotes true ; written T in Lisp) #f(denotes false ; written NIL in Lisp) Lisp/Scheme Data Types

59 Non-atomic S-expressions: If s1 and s2 are s-expressions, so is (s1. s2) Important primitive functions: cons[ s1, s2] = (s1. s2) car[ (s1. s2) ] = s1 cdr[ (s1. s2) ] = s2 cadr[ s ] = car[ cdr[ s ] ] cadar[ s ] = car[ cdr[ car[ s ] ] ] Important: Everything in LISP/Scheme is an s-exp. Important: Best to think in terms of how s-exps are stored internally: binary trees (using pointers) Lisp/Scheme Data Types (contd.) CSE 3341/655; Part 4

60 List Notation: ( ) denotes NIL (6) denotes (6. NIL) (6 5) denotes (6. (5. NIL)) (6 5 5) denotes (6. (5. (5. NIL))) ((1. 2) 3) denotes ((1. 2). (3. NIL)) ((1. 2) (3. 4)) denotes ((1. 2). ((3. 4). NIL)) In general: (s1) denotes (s1’. NIL)[s1’ : "dot version" of s1 ] (s1 s2) denotes (s1’. (s2’. NIL)) (s1 s2 s3... ) denotes (s1’. (s2’. (s3’. NIL))) etc. List Notation

CSE 3341/655; Part 4 61 The Scheme/LISP interpreter converts everything to “dot” notation; list notation is only for input/output Convert: ((1. 3) 2 4)((1. 3) (2. 4))((1. 3) (2 4)) (1. (2. NIL))((1. NIL). (2. NIL))((1. 2). NIL) (1. (2. 3))((1 3) (2 4)) Consider car, cdr, cddr etc. of ((1. 2) (3. 4)), ((1. 2). (3. 4)) etc. car, cdr, cons are best understood in terms of how they manipulate s-expressions internally. List Notation (contd.)

CSE 3341/655; Part 4 62 More functions: eq?[ x, y ] : returns #t or #f if x, y are/are not same atom eq?[ #t, #f ] = #f eq?[ #f, #f ] = #t eq?[ #f, 5 ] = #f : arguments to eq? must be atoms pair?[ x ] : returns #t if x is a "pair"; #f otherwise pair?[ (2. 3) ] = #t pair?[ (2. #t) ] = #t pair?[ #t ] = #f pair?[ () ] = #f null?[ x ] : returns #t if x is (); #f otherwise Built-in Functions

CSE 3341/655; Part 4 63 Standard math functions (arguments must be numbers): +[ 10, -5 ]= 5 -[ 10, -5 ] = 15 *[ 10, -5 ]= -50 /[ 10, 5 ] = 2 /[ 10, 7 ] = 10/7 >[ 10, -5 ]= #t =[ 10, -5 ]= #f... many others; but we won't use most of them ***Introduce actual notation at this point; don't use design notation*** Important: We have not yet seen any Scheme programs The above are just meanings of these built-in functions Built-in Functions (contd.)

CSE 3341/655; Part 4 64 Important: Atoms are used for three purposes: Constants: numbers, #t, #f (we won't use string consts.) Function names: car, cdr, eq?, +, >,... Function parameters (in function definitions) Important: Distinction between parameters and arguments (also: "formal parameters" and "actual arguments") Atoms, Parameters, Arguments

CSE 3341/655; Part 4 65 addUpList[ L ] : return sum of nos. in L (a list of nos.) addUpList[ L ] ::; "design notation", not Lisp/Scheme [ null?[ L ]  0 | #t  +[ car[L], addUpList[ cdr[L] ] ] ] addUpList[ (2 3 4) ] : returns 9; how does it work? nNil[ n ] : if n is 4 return (NIL NIL NIL NIL) nNil[ n ] :: [ =[ n, 0]  NIL | #t  cons[ NIL, nNIL[ -[n, 1] ] ] ] doubleUp[ s ] :: cons[ s, s ] ; what does it do? length[ L ] :: ; should return length of list L mystery[L] :: nNil[ length[ L ] ] ; what does it do? Defining New Functions

CSE 3341/655; Part 4 66 Starting Scheme (on stdlinux): % scheme48... welcome,... Type,? for help ; type in a Scheme expression; the interpreter evaluates ; it, outputs the value, waits for the next Scheme exp. >,exit Simplest Scheme expression: constant atoms: % scheme48 > 655 655 Scheme/Lisp "Programs"

67 Function application: F[a1, a2, a3,..., an]  (F a1 a2 a3... an) The interpreter *evaluates* a1, a2,..., an; binds the resulting values to p1, p2,..., pn, the pars of F; then it evaluates the body of F (as a Scheme exp) > (+ (+ 2 3) (* 5 6) ) ; evaluates (+ 2 3), (* 5 6), binds to pars of +, then ; evaluates body of + [using values bound to pars when ; needed] > (cons (+ 2 3) (* 5 6) ) ; similar; result: (5. 30) > (cons A B) ; error! "unbound A, B" > (cons #t #f) ; okay! #t, #f evaluate to #t, #f Scheme/Lisp Expressions CSE 3341/655; Part 4

68 > (quote A) ; Don't evaluate A A (quote...) looks like a function call; but it is not; it can't be! It is a form [also "special form"]; only three special forms > (cons (cdr (A. B) ) (car (A. B) ) ) ; Error! > (cons (cdr (quote (A. B)) ) (car (quote (A. B)) ) ) (B. A) > (cons (quote (cdr (A. B)) ) (quote (car (A. B)) ) ) ??? Quoted expressions

(cond (b1 e1) (b2 e2)... (bn en) ) : each bi, ei is a Scheme/Lisp expression To evaluate: Evaluate b1; if value is #t, evaluate e1, return that value if b1 value is #f, evaluate b2; if #t, eval e2, return that val if b2 value is #f, evaluate b3; if #t, eval e3, return that val... if b(n-1) value is #f, eval bn; if #t, eval en, return that val else... error! (cond ( (> 5 3) 3 ) ( #t (3. 5) ) ) (cond ( (> 3 5) (cons 3 5) ) ( #t (cons 5 3) ) ) Conditional expressions (Another Special Form) 69 CSE 3341/655; Part 4

70 (define (F p1 p2... pn)..body (Scheme exp.).. ) > (define (silly p1 p2) 5)..okay.. [or some such acknowledgment] > (silly 10 20) 5 > (silly (10. 20) (20. 30)) Error! > (silly (cons 10 20) (cons 20 30)) 5 > (silly (quote (10. 20)) (cons 20 30)) 5 Function Definitions (Sp. Form)

CSE 3341/655; Part 4 71 xmemb[x, list] ::; is x a member of list? [null?[list]  #f |eq?[x, car[list]]  #t |#t  xmemb[x, cdr[list]] ] >(define(xmemb x list); is x a member of list? (cond ( (null? list)#f) ((eq? x (car list)) #t ) ; quote list? ( #t (xmemb x (cdr list) )) ) ) ; no values returned >(xmemb 3 (quote (2 3 4)) ) #t Defining new functions (contd)

CSE 3341/655; Part 4 72 equal[ x, y ] :: ; x and y may not be atoms [ pair?[x]  [pair?[y]  [equal[car[x],car[y]]  equal[cdr[x],cdr[y]]; | #t  #f] | pair?[y]  #f ; why? | #t  eq?[x,y]] > (define (equal x y) (cond( (pair? x) (cond... ) ) ( (pair? y) #f ) ( #t (eq? x y)) ) ) > (define (atom? x)...) ??? Function Definitions (contd.)

CSE 3341/655; Part 4 73 xunion[s1, s2] ::; union of atomic lists, less duplicates [null?[s1] --> s2 |null?[s2]--> s1 |#t-->[xmemb[car[s1],s2]-->xunion[cdr[s1], s2] |#t --> cons[ car[s1], xunion[cdr[s1], s2] ] ] ] ; better: xunion[s1, s2] :: [null?[s1] --> s2 |null?[s2]--> s1 |xmemb[car[s1],s2]-->xunion[cdr[s1], s2] |#t --> cons[ car[s1], xunion[cdr[s1], s2] ] ] Defining new functions (contd)

CSE 3341/655; Part 4 74 addUpList[ L ] :: [ null?[ L ]  0 | #t  +[ car[L], addUpList[ cdr[L] ] ] ] > (define (addUpList L) (cond ( (null? L) 0 ) ( #t (+ (car L) (addUpList (cdr L) ) ) ) ) ).. okay.. > (addUpList (2 3 4) ) Error! > (addUpList (quote (2 3 4) ) ) 9 ; but how does it work? Function Definitions (contd.)

CSE 3341/655; Part 4 75 nNil[ n ] :: [ =[ n, 0]  NIL | #t  cons[ NIL, nNIL[ -[n, 1] ] ] ] > (define (nNil n) (cond ((= n 0) (quote ()) ) ; why? (#t (cons '() (nNil (- n 1))) ) ) ) doubleUp[ s ] :: cons[ s, s ] (define (dUp s) (cons s s) ) ; need to quote s? Function Definitions (contd.)

maxList[L] :: ; returns max of number in non-empty list L ; Functional: [null?[cdr[L]]-->car[L] |>[car[L], maxList[cdr[L]]-->car[L] |#t--> maxList[cdr[L]] ] ; Functional but better: [null?[cdr[L]]-->car[L] |#t--> bigger[ car[L], maxList[cdr[L]]] ] ; define bigger ; imperative: maxList[L] = max2[car[L], cdr[L]] max2[x, L] :: [null?[L]--> x |>[x, car[L]]--> max2[x, cdr[L]] |#t--> max2[ car[L], cdr[L] ] ] Different styles in Lisp 76 CSE 3341/655; Part 4

77 How do you obtain first element of a list? How do you obtain the last element? [watch out!] How do you append two lists? [No, not just cons!] How do you reverse a list? [best: use imperative trick] More functions

CSE 3341/655; Part 4 78 Five types of Lisp expressions ("programs"): Constants: 4, 5, #t etc.: Evaluate to themselves [4, 5 etc] Symbols:X, Y, etc. Look them up on the "association" list [a-list]. Function application: (F a1 a2 a3... an) F is a (built-in or user-defined) function that expects n parameters; each ai is a Lisp expression; Evaluate each ai; bind that value aiv to pi, the corr. parameter, by adding (pi. aiv) to the a-list; then evaluate the body of F How Lisp interpreter works

CSE 3341/655; Part 4 79 Quoted exp: (QUOTE s) : where s is any s-exp; evaluates to s Conditional: (COND (b1 e1) (b2 e2)... (bn en) ) b1, b2,... and e1, e2,... are all Lisp expressions; eval. b1, b2,... to find the first bj that eval's to non-NIL; eval corr. ej & return its value; if all bi's eval to NIL, error! Fn. def.: (DEFINE (F p1... pn) fe) : F is new fn., p1,..., pn its parameters, fe the body; save def. on "d-list". Lisp Exps./How they are eval'd (contd)

Three key functions: eval:evaluates a Lisp-exp. evcon:evaluates a conditional Lisp-exp. apply:applies a function to given set of arguments interpreter[exp, dList] = eval[exp, NIL, dList] ; why? evcon[pairs, aList, dList] = [null?[pairs]-->"error"! |eval[caar[pairs],aList,dList] --> eval[cadar[pairs],aList,dList] |#t --> evcon[cdr[pairs], aList, dList] ] Lisp Interpreter (partial) (*in* Lisp!) 80 CSE 3341/655; Part 4

eval[ exp, aList, dList] = [atom?[exp] -->[int?[exp]-->exp |eq?[exp,#t]-->#t |eq?[exp,#f]-->#f |in?[exp,aList]-->getVal[exp,aList] |#t--> "unbound variable!" ] |atom?[car[exp]] --> [eq?[car[exp],QUOTE] --> cadr[exp] |eq?[car[exp],COND] --> evcon[cdr[exp], aList, dList] |#t --> apply[car[exp], evlis[cdr[exp],aList,dList], aList, dList] ] |#t--> "error!" ] Lisp Interpreter (partial) (contd.) 81 CSE 3341/655; Part 4

82 Differences (with LISP): #t and #f : for "true" and "false" [Lisp uses T, NIL for this] NIL always written as () and is not a normal atom; In fact, Scheme talks of "pairs" vs. "non-pairs", not "atoms" and "non-atoms" Scope rule What "scope rule" means How it works in Lisp/Scheme Elimination of some imperative features Scheme vs. LISP

Download ppt "CSE 3341/655; Part 4 55 A functional program: Collection of functions A function just computes and returns a value No side-effects In fact: No program."

Similar presentations