Documents
Resources
Learning Center
Upload
Plans & pricing Sign in
Sign Out
Get this document free

lec9

VIEWS: 1 PAGES: 41

									CS 2104 : Prog. Lang. Concepts.

 Functional Programming I




 Lecturer : Dr. Abhik Roychoudhury
            School of Computing
   From Dr. Khoo Siau Cheng’s lecture notes
                     Outline

•   What is Functional Programming?
•   Basic Expressions
•   Using Higher-order Functions
•   List Processing
•   Value and Type Constructions
    Features of Functional Programming

•   Expressions: The main construct in the language
•   Functions : First-class citizens of the language
•   Types : for specification and verification
•   List Processing
                     Computation

• Achieved via function application
• Functions are mathematical functions without
  side-effects.
   – Output is solely dependent of input.
                                    States


            Pure                    Impure
          function                 function
                               with assignment
                     Outline

•   What is Functional Programming?
•   Basic Expressions
•   Using Higher-order Functions
•   List Processing
•   Value and Type Constructions
      Basic SML Expressions

<Exp> ::= <Constants> | <Identifiers>
   | <Exp1> <op> <Exp2> |
   | if <Exp0> then <Exp1> else <Exp2>
   | let {<Decl>} in <Exp> end
   | fn <Pattern> {<Pattern>} => <Exp>
   | <Exp1> <Exp2>
   | (<Exp1>, <Exp2> {, <Exp3>})
   | <List-Exp>
<Constants>   ::= all constants
<Identifiers> ::= all identifiers
<op>          ::= all binary operators
If-expression, Not If-statement
  if <e0> then <e1> else <e2>


if (3 > 0)
 then 4+x              4+x
 else x-4 ;


 If-expression evaluates to a value.
      Constructing a Linear List
<List-Exp> ::=[[<Exp> {, <Exp>}] ]
             | nil | <Exp> :: <Exp>
nil ;
1::nil ;         Note : A list must end with nil.
1::(2::nil);
(x+2)::(y-3)::(x*3)::nil ;
        Constructing a Linear List
  <List-Exp> ::=[[<Exp> {, <Exp>}] ]
               | nil | <Exp> :: <Exp>
  nil ;
  1::nil ;         Operator :: is right associative.
  1::(2::nil);
  (x+2)::(y-3)::(x*3)::nil ;
head
                           tail

  [] ; [1] ; [1,2]; [x+2,y-3,x*3] ;
               Constructing a Tuple

         (<Exp> , <Exp> {, <Exp>})

Tuple is like a record without field names.

   (1,2) ;

   (1,2,True,4,False) ;

   (x+2,y=3,x*3) ;
       Giving An Expression A Name
Declaring an expression with a name enables easy reference.

   <decl> ::= val <pattern> = <exp>

Identifiers are legally declared after proper pattern matching.

   val   x = 3      ;
   val   (y,z)      = (x+3,x-3) ;
   val   [a,b]      = [x+2,y-3] ;
   val   [a,b]      = [x+2] ;
   val (x::xs) = [1,2,3,4,5] ;
       Pattern-Match a List

val (x::xs) = [1,2,3,4,5] ;
  x  1
  xs  [2,3,4,5] ;

val (x::_::y::xs) = [1,2,3,4,5] ;
 x  1
 y  3
 xs  [4,5] ;
      Local Declaration/Definition
  let {<decl>} in <exp> end


let  val x = (3,4)
     val (a,b) = x      15
in   a + a * b
end ;


  Identifiers are statically scoped
      Nested bindings of same var.

• Let val x =2 in let val x = x +1 in x*x end end

• Let val x = 2 in let val y = x +1 in y * y end end

• Let val x = 2 in (x+1)*(x+1) end

• 9
         Function Declaration and
           Function Application
  <Decl> ::= fun <var> <para> = <exp>
  <para> ::= <pattern> {<pattern>}

   fun fac x = if (x > 0)
               then x * (fac (x-1)) else 1
fac 2  if (2 > 0) then 2 * (fac (2-1)) else 1
 2 * (fac 1)
 2 * (if (1 > 0) then 1 * (fac (1-1)) else 1)
 2 * (1 * (fac 0))
 2 * (1 * 1)
 2
               Function as Equations
 A function can be defined by a set of equations.

<Decl> ::= fun <var> <para> = <exp>
            {| <var> <para> = <exp>}
     fun fac 0             = 1
     |   fac n             = n * (fac (n-1))
 Function application is accomplished via pattern matching.

fac 2  2 * (fac (2-1))                  2 * (fac 1)
  2 * (1 * (fac (1-1)))                 2 * (1 * (fac 0))
  2 * (1 * 1)                           2
                     Outline

•   What is Functional Programming?
•   Basic Expressions
•   Using Higher-order Functions
•   List Processing
•   Value and Type Constructions
   Functions as First-Class Citizens
Lambda abstraction: A nameless function
         fn <para> => <Exp>

(fn (x,y) => x + y) (2,3)  2+3  5
     Definition
                  Application


val newfn = fn (x,y) => x + y ;

newfn(2,4) + newfn(4,3)
   Functions as First-Class Citizens
Passing function as argument
  fun apply (f, x) = f x

apply (fac, 3)      fac 3
                    6
apply (fn x => x*2, 3)
      (fn x => x*2) 3
      3*2
      6
    Functions as First-Class Citizens
 Returning function as result
 fun choose (x,f,g) = if x then f else g ;
 choose(a = b,fn x => x*2, fac)(4)
       returns either 8 or 24
fun compose (f,g) = fn x => f (g x)
(compose (add3,fac)) 4
 (fn x => add3 (fac x))(4)
 (add3 (fac 4))
                    compose (f,g) is denoted as f o g
 27
   Functions as First-Class Citizens
Storing function in data structure
 val   flist = [ fac, fib, add3] ;

 let val [f1,f2,f3] = flist
 in (f1 2) + (f2 3) + (f3 4)
 end ;
          Functions as Algorithms
• A function describes a way for computation.
• Self-Recursive function

fun    factorial (x) = if (x <= 1) then 1
                       else x * factorial (x-1) ;

• Mutual-Recursive functions
fun   even(0)         = true
|     even(1)         = false
|     even(x)         = odd(x-1)
and   odd(x)          = even(x-1) ;
     Passing Arguments to a Function
How many argument does this function really take?
       fun f (x,y) = x + 2 * y ;

                 a pair
        Calling f with argument (1,2) yields 5.

       fun g x y = x + 2 * y ;

    pattern 1         pattern 2

       Calling g with arguments 1 and 2 yields 5.
                     Outline

•   What is Functional Programming?
•   Basic Expressions
•   Using Higher-order Functions
•   List Processing
•   Value and Type Constructions
                   Exploring a List
fun length []      = 0
|   length (x::xs) = 1 + length(xs) ;

length([10,10,10]) ==>            1   +   length([10,10])
                   ==>            1   +   1 + length([10])
                   ==>            1   +   1 + 1 + length([])
                   ==>            1   +   1 + 1 + 0
                   ==>            3
Note how a list is being consumed from head to tail.
fun append([],ys)    = ys
|   append(x::xs,ys) = x :: append(xs,ys);

append([1,2],[3]) ==> 1::append([2],[3])
               ==> 1::2::append([],[3])
               ==> 1::2::[3]
               ==> [1,2,3]

Note how a new list is being produced from head to tail.

append(x,y) is denoted by x @ y.
fun rev(xs) =
     let fun r([],ys) = ys
         |   r(x::xs,ys)= r(xs,x::ys)
     in r(xs,[])end

rev([1,2,3]) ==> r([1,2,3],[])
          ==> r([2,3],1::[])
          ==> r([3],2::1::[])
          ==> r([],3::2::1::[])
          ==> [3,2,1]

Note how lists are being produced and consumed
concurrently.
             Map operation
map square [1,2,3,4]
     ==> [square 1, square 2,.., square 4]
     ==> [1,4,9,16]

fun map f [] = []
|   map f (x::xs) =
          (f x) :: (map f xs)
map square [1,2]
     ==> (square 1) :: (map square [2])
     ==> 1 :: (square 2) :: (map square [])
     ==> 1 :: 4 :: []
     == [1,4]
                Map operation
        fun map f [] = []
        |   map f (x::xs) =
                  (f x) :: (map f xs)

Law for Map :
map f (map g list) = map (f o g) list
      map f (map g [a1,..,an])
      = map f [g a1,..,g an]
      = [f (g a1),.., f (g an)]
      = [(f o g) a1,.., (f o g) an]
      = map (f o g) [a1,..an]
                 Reduce Operation
reduce  [a1,..,an] a0 =
          a1  (a2  (..  (an  a0)))
reduce f [a1,..,an] a0 =
          f(a1,f(a2,f(..,f(an,a0))))

        :                           
   a1        :                 a1        
        a2       :                  a2       
                      :                           
                 an       []                 an       a0
reduce (op *) [2,4,6] 1
     ==> 2 * (4 * (6 * 1))
     ==> 48
reduce (fn (x,y)=>1+y) [2,4,6] 0
     ==> 1 + (1 + (1 + 0))
     ==> 3

       :                    +

   2       :            1       +
       4       :            1       +
           6       []           1       0
                     Outline

•   What is Functional Programming?
•   Basic Expressions
•   Using Higher-order Functions
•   List Processing
•   Value and Type Constructions
              Types:
Classification of Values and Their
            Operators
Basic Types
Type           Values               Operations
bool           true,false           =, <>, …
int            …,~1,0,1,2,…         =,<>,<,+,div,…
real           ..,0.0,.,3.14,..     =,<>,<,+,/,…
string         “foo”,”\”q\””,…      =,<>,…

Boolean Operations:
         e1 andalso e2        e1 orelse e2
                  Types in ML

• Every expression used in a program must be well-
  typed.
   – It is typable by the ML Type system.
• Declaring a type :
         3 : int
         [1,2] : int list
• Usually, there is no need to declare the type in
  your program – ML infers it for you.
              Structured Types
 Structured Types consist of structured values.
 • Structured values are built up through
   expressions. Eg : (2+3, square 3)
 • Structured types are denoted by type
   expressions.
<type-expr>       ::= <type-name> | <type-constant>
               | <type-expr> * <type-expr>
                  | <type-expr>  <type-expr>
                | <type-expr> list
                  |…
                Type of a Tuple
                    (1,2) : int * int
      (3.14159, x+3,true) : real * int * bool


         A * B = set of ordered pairs (a,b)

Data Constructor :        (,)      as in (a,b)
Type Constructor        : *        as in A * B


In general,
      (a1,a2,…,an) belongs to      A1*A2*…*An.
               Type of A List
Type Constructor :            list
                     [1,2,3] : int list
              [3.14, 2.414] : real list
             [1, true, 3.14] : ??       Not well-typed!!
A list = set of all lists of A -typed values.
A in A-list refers to any types:
      (int*int) list   : [ ], [(1,3)], [(3,3),(2,1)], …
      int list list    : [ ], [[1,2]], [[1],[0,1,2],[2,3],…
         Function Types
 Declaring domain & co-domain
              fac : int -> int

 A -> B = set of all functions from A to B.
Type Constructor :        ->
Data Construction via :
1. Function declaration : fun f x = x + 1 ;
2. Lambda abstraction : fn x => x + 1;

Value Selection via function application:
                    f3        4
      (fn x => x + 1) 3       4
               Sum of Types
             Enumerated Types
datatype Days   = Mo | Tu | We | Th | Fr | Sa | Su ;

  New Type
                     data / data constructors


 Selecting a summand via pattern matching:
        case d
         of    Sa => “Go to cinema”
         |     Su => “Extra Curriculum”
         |     _ => “Life goes on”
   Combining Sum and Product of Types:
           Algebraic Data Types

Defining an integer binary tree:
datatype IntTree = Leaf int |
               Node of (IntTree, int, IntTree) ;

fun height (Leaf x) = 0
|   height (Node(t1,n,t2))=
          1 + max(height(t1),height(t2)) ;
                    Conclusion

• A functional program consists of an expression,
  not a sequence of statements.
• Higher-order functions are first-class citizen in the
  language.
   – It can be nameless
• List processing is convenient and expressive
• In ML, every expression must be well-typed.
• Algebraic data types empowers the language.

								
To top