Chapter 15 – Functional Programming Languages CSCE 343
List Functions List functions have list parameters EVAL should not try to evaluate quote function: avoids evaluation of parameters takes one parameter returns the parameter without evaluation: e.g.: (quote (a b)) Short-hand notation: ‘(a b)
List Functions to Dismantle CAR: returns first element of list Return value can be atom or list Parameter must be a list. >(car ‘(a b c d)) CDR: returns list after removing first element Return value is always a list Parameter must always be a list >(cdr ‘(a b c d))
List Functions (car ‘( (a b c) d e)) (cdr ‘(a (b c) d)) (cdr ‘(a)) (cdr ‘()) --is an error (car ‘()) --is an error (define (second l) (car (cdr l)))
List Functions to Build cons: add first parameter as first element of second list First parameter: atom or list, second parameter must be a list (or you get dotted pair) list: construct list from variable number of parameters >(cons ‘(a b) ‘(c d)) -- returns ((a b) c d) >(list ‘one ‘to ‘one) -- returns (one to one)
List Functions to Build >(cons ‘h ‘(e l p)) -- returns (h e l p) >(cons ‘h ‘( )) -- returns (h) >(cons (car lst) (cdr lst) ) -- returns list lst >(cons h ‘(e l p)) -- is an error >(cons 5 ‘(e l p)) -- returns (5 e l p) >(list 3 ‘on 2) -- returns (3 on 2)
Predicate: eq? and eqv? eq? takes two parameters; returns #t if they are the same symbolic atom Must be atoms, if lists, result is unreliable Should use = for numeric atoms eqv? works with both symbolic and numeric atoms (slower than eq? and =) >(eq? ‘a ‘a) -- returns #t >(= 5 5) -- returns #t >(eq? ‘(a b) ‘(a b)) -- returns ??? -- who knows >(eqv? 5 5) -- returns #t >(eqv? ‘a ‘a) -- returns #t
Predicate: list? and null? list? takes one parameter, returns #t if a list #f otherwise >(list? ‘a) null? takes one parameter; returns #t if it is the empty list >(null? ‘())
Simple List Membership Define the function (member2 atm list) > (member2 ‘b ‘(a b c) ) -- returns true Write a recursive definition
Simple List Membership (define (member2 atm list) (cond ((null? list) #f) ((eq? atm (car list)) #t) ( else (member2 atm (cdr list))) )) Define a function (equalsimp lis1 lis2) Returns true if the two simple lists are equal Write a recursive definition
Example w/ recursion ;;determine if two simple lists are equal (DEFINE (equalsimp lis1 lis2) (COND ((NULL? lis1) (NULL? lis2)) ((NULL? lis2) #f) ((EQ? (CAR lis1) (CAR lis2)) (equalsimp(CDR lis1)(CDR lis2))) (ELSE #f) ) Write a recursive definition that solves the problem for any two parameters
Equal For Any Pair of Expressions (DEFINE (equal lis1 lis2) (COND ((NOT (LIST? lis1))(EQ? lis1 lis2)) ((NOT (LIST? lis2)) #f) ((NULL? lis1) (NULL? lis2)) ((NULL? lis2) #f) ((equal (CAR lis1) (CAR lis2)) (equal (CDR lis1) (CDR lis2))) (ELSE #f) ) Equivalent to system predicate function equal?
Example: append (DEFINE (myappend lis1 lis2) (COND ((NULL? lis1) lis2) (ELSE (CONS (CAR lis1) (myappend (CDR lis1) lis2))) ) Equivalent to system function append.
let Form: (let ( (name_1 expression_1) (name_2 expression_2) … (name_n expression_n)) expression {expression} )
Example with let (DEFINE (quadratic_roots a b c) (LET ( (root_part_over_2a (/ (SQRT (- (* b b) (* 4 a c)))(* 2 a))) (minus_b_over_2a (/ (- 0 b) (* 2 a))) ) (DISPLAY (+ minus_b_over_2a root_part_over_2a)) (NEWLINE) (DISPLAY (- minus_b_over_2a root_part_over_2a)) ) Let defines two variables (root_part_over_2a, minus_b_over_2a) that have local scope
Functional Forms Composition: already used it >(cdr (cdr ‘(a b c))) returns (c) Apply to all: (DEFINE (mapcar fun lis) (COND ((NULL? lis) '()) (ELSE (CONS (fun (CAR lis)) (mapcar fun (CDR lis)))) ) >(mapcar sqrt ‘(4 9 25))
Other Functional Languages You may skip sections 15.6-15.8 Common Lisp ML Haskell