TI1220 Lecture 6: First-class Functions
Upcoming SlideShare
Loading in...5
×
 

TI1220 Lecture 6: First-class Functions

on

  • 1,305 views

 

Statistics

Views

Total Views
1,305
Views on SlideShare
418
Embed Views
887

Actions

Likes
0
Downloads
16
Comments
0

1 Embed 887

http://department.st.ewi.tudelft.nl 887

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

TI1220 Lecture 6: First-class Functions TI1220 Lecture 6: First-class Functions Presentation Transcript

  • Lecture 6: First-Class Functions TI1220 2012-2013 Concepts of Programming Languages Eelco Visser / TU Delft
  • Messages from the Lab
  • Graded Assignment 1 Algebraic datatypes in C Dynamic dispatch in CImportant dates Deadline: April 2, 2013 23:59 Extension: April 5, 2013 23:59 Submitting after extension date is not possible Maximum penalty for submitting after deadline: 6 points Minimum grade needed: 4 Grade: 70% unit tests, 30% check lists Grade for GAs: average of four assignments
  • Alonzo Church (June 14, 1903 – August 11, 1995) wasan American mathematician and logician who made majorcontributions to mathematical logic and the foundations oftheoretical computer science. He is best known for thelambda calculus, Church–Turing thesis, proving theundecidability of the Entscheidungsproblem, Frege–Churchontology, and the Church–Rosser theorem.The lambda calculus emerged in his famous 1936 paper showing the unsolvability ofthe Entscheidungsproblem. This result preceded Alan Turings famous work on thehalting problem, which also demonstrated the existence of a problem unsolvable bymechanical means. Church and Turing then showed that the lambda calculus and theTuring machine used in Turings halting problem were equivalent in capabilities, andsubsequently demonstrated a variety of alternative "mechanical processes forcomputation." This resulted in the Church–Turing thesis.The lambda calculus influenced the design of the LISP programming language andfunctional programming languages in general. The Church encoding is named in hishonor. http://en.wikipedia.org/wiki/Alonzo_Church
  • Outline Lambda calculus First-class functions in JavaScript Functions as objects in Java First-class functions in Scala Generic, higher-order functions Control abstraction
  • Lambda Calculus
  • Syntax• Variables: x• Functions: λ x . M Lambda Calculus• Application: (M N)Semantics• Beta reduction: (λ x . M) N ≡ M[x := N]Example• ((λ c . (λ x . c)) 1) 2 ≡ (λ x . 1) 2 ≡ 1
  • Free Variables Lambda Calculus• fvs(x) ≡ {x}• fvs(λ x . M) ≡ fvs(M) / {x}• fvs(M N) ≡ fvs(M) ∪ fvs(N)Example• fvs(λ c . x (λ x . z c)) ≡ {x, z}
  • Lambda CalculusSubstitution• x [x := N] ≡ N• y [x := N] ≡ y if x ≢ y• (λ x . M) [x := N] ≡ λ x . M• (λ y . M) [x := N] ≡ λ y . (M [x := N]) if x ≢ y, y ∉ fvs(N)• (M N) [x := P] ≡ (M[x := P])(N[x := P])Example• (λ x . (λ z . x z) (x z)) [z := k] ≡ (λ x . (λ z . x z) (x k))
  • What is the relevance of the lambda calculus?
  • Lambda = first-class function Beta reduction = function evaluationLambda calculus = essence of functional programminginstantiated in many modern programming languages
  • First-order functions• Function definition Functions are Values• Function callFirst-class functions• unnamed function literals (x: Int) => x + 1• pass functions around as values: return as result, pass as parameter, store in data structure
  • Code reuse• name and parameterize expressions and statementsFunctional abstraction in Java• methodsFunctional abstraction in Scala• nested functions• function literals• function values
  • First-Class Functions in JavaScript
  • // Print the name and value of each property of o. Return undefined.function printprops(o) { for ( var p in o) console.log(p + ": " + o[p] + "n");}// Compute the distance between Cartesian points (x1,y1) and (x2,y2).function distance(x1, y1, x2, y2) { var dx = x2 - x1; var dy = y2 - y1; return Math.sqrt(dx * dx + dy * dy);}// A recursive function (one that calls itself) that computes factorials// Recall that x! is the product of x and all positive integers less than it.function factorial(x) { if (x <= 1) return 1; return x * factorial(x - 1);} Named Function Definitions
  • Anonymous Function Expressions// This function expression defines a function that squares its argument.// Note that we assign it to a variablevar square = function(x) { return x * x;}// Function expressions can include names, which is useful for recursion.var f = function fact(x) { if (x <= 1) return 1; else return x * fact(x - 1);};// Function expressions can also be used as arguments to other functions:data.sort(function(a, b) { return a - b; });// Function expressions are sometimes defined and immediately invoked:var tensquared = (function(x) { return x * x; }(10));
  • var incrementer = Nested functions: Closures function (base) { return function (x) { return x + base; }; };var inc3 = incrementer(3);inc3(39); remember value of baseincrementer = base . ( x . (x + base))inc3 = incrementer 3;inc3 39 In lambda notation
  • var scope = "global scope"; // A global variable Closuresfunction checkscope() { var scope = "local scope"; // A local variable function f() { return scope; } // Return the value in scope here return f();}checkscope() // => "local scope" var scope = "global scope"; // A global variable function checkscope() { var scope = "local scope"; // A local variable function f() { return scope; } // Return the value in scope here return f; } checkscope()() // What does this return?
  • var uniqueInteger = (function() { // Define and invoke var counter = 0; // Private state of function below return function() { return counter++; }; Closures with state}()); function counter() { var n = 0; return { count: function() { return n++; }, reset: function() { n = 0; } }; } var c = counter(), d = counter(); // Create two counters c.count() // => 0 d.count() // => 0: they count independently c.reset() // reset() and count() methods share state c.count() // => 0: because we reset c d.count() // => 1: d was not reset
  • // This function returns a function that always returns vfunction constfunc(v) { return function() { return v; }; }// Create an array of constant functions:var funcs = [];for(var i = 0; i < 10; i++) funcs[i] = constfunc(i);// The function at array element 5 returns the value 5.funcs[5]() // => 5 Accidental closure state // Return an array of functions that return the values 0-9 function constfuncs() { var funcs = []; for ( var i = 0; i < 10; i++) funcs[i] = function() { return i; }; return funcs; } var funcs = constfuncs(); funcs[5]() // What does this return?
  • function compose(f, g) { return function() { // We use call for f because were passing a single value // and apply for g because were passing an array of values. return f.call(this, g.apply(this, arguments)); };}var square = function(x) { return x * x; Higher-Order Functions};var sum = function(x, y) { return x + y;};var squareofsum = compose(square, sum);squareofsum(2, 3) // => 25
  • function incList(xs) { var ys = []; for(i in xs) { ys[i] = xs[i] + 1; } return ys;}incList([1, 2, 3]) // returns [2, 3, 4]function map(f, xs) { Higher-Order Functions var ys = []; for(i in xs) { ys[i] = f(xs[i]); } return ys;}function incList2(xs) { return map(function (x) { return x + 1; }, xs);}incList2([1, 2, 3]) // returns [2, 3, 4]
  • Functions as Objects in Java
  • Does Java support first-class functions?
  • interface IntFun { Int apply(Int x)}class Inc implements IntFun { Int apply(Int x) { return x + 1; }}class Foo { void f(IntFun g) { g.apply(...) }} ... foo.f(new Inc) ... Functions as Objects in Java
  • First-Class Functions in Scala
  • Function Literals((c: Int) => ((x: Int) => c+x))(1)(2)evaluation steps:- ((x: Int) => 1+x) (2)- 1+2- 3
  • scala> var increase = (x: Int) => x + 1 Function Values are Objectsincrease: (Int) => Int = <function1>scala> increase(10)res0: Int = 11scala> increase = (x: Int) => x + 9999increase: (Int) => Int = <function1>scala> increase(10)res1: Int = 10009scala> increase.apply(10)res37: Int = 11 <function>(<args>) abbreviates <function>.apply(<args>)
  • Generic Higher-Order Functions (in Scala)
  • Re-occurring patterns• transform every element of a list• verify property of all elements of a list• extract elements satisfying some criterion• combining elements of a list using some operatorHigher-order functions• direct, reusable definitions of such patterns
  • def inc(xs: IntList): IntList = xs match { case Nil() => Nil() case Cons(y, ys) => Cons(y + 1, inc(ys))}def square(xs: IntList): IntList = xs match { case Nil() => Nil() case Cons(y, ys) => Cons(y * y, square(ys))} Transform each element of a list
  • Factor out the transformation def map(xs: IntList, f: Int => Int): IntList = xs match { case Nil() => Nil() case Cons(y, ys) => Cons(f(y), map(ys, f)) } def inc(xs: IntList) = map(xs, ((x:Int) => x + 1)) def square(xs: IntList) = map(xs, ((x:Int) => x * x))
  • Lists in Scala Library val fruit : List[String] = List("apples", "oranges", "pears") val nums: List[Int] = List(1, 2, 3, 4) val diag3: List[List[Int]] = List( List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) val empty = List()Lists are polymorphic: parameterized with type of elements
  • Factor out type A => B : type of functions from type A to type B def map[A,B](xs: List[A], f: A => B): List[B] = xs match { case List() => List() case y :: ys => f(y) :: map(ys, f) } val l = map(List(1, 2, 3), ((x: Int) => x + 1)) Polymorphic function: parameterized with types
  • scala> List(1, 2, 3) map (_ + 1) Map in Scala Libraryres29: List[Int] = List(2, 3, 4)scala> val words = List("the", "quick", "brown", "fox")words: List[java.lang.String] = List(the, quick, brown, fox)scala> words map (_.length)res30: List[Int] = List(3, 5, 5, 3)scala> words map (_.toList.reverse.mkString)res31: List[String] = List(eht, kciuq, nworb, xof)scala> words map (_.toList)res32: List[List[Char]] =List(List(t,h,e), List(q,u,i,c,k), List(b,r,o,w,n), List(f,o,x))scala> words flatMap (_.toList)res33: List[Char] = List(t,h,e,q,u,i,c,k,b,r,o,w,n,f,o,x)
  • Select Elements in a List def even(xs: IntList): IntList = xs match { case Nil() => Nil() case Cons(y, ys) => if(y % 2 == 0) Cons(y, even(ys)) else even(ys) } def primes(xs: IntList): IntList = xs match { case Nil() => Nil() case Cons(y, ys) => if(isPrime(y)) Cons(y, primes(ys)) else primes(ys) }
  • def filter(xs: IntList, p: Int => Boolean): IntList =xs match { case Nil() => Nil() case Cons(y, ys) => if(p(y)) Cons(y, filter(ys, p)) else filter(ys, p)}def evenF(xs: IntList) = filter(xs, ((x: Int) => x % 2 == 0))def primes(xs: IntList) = filter(xs, isPrime _) Factor out Predicate
  • Factor out Type of Elementsdef filter[A](xs: List[A], p: A => Boolean): List[A] = xs match { case List() => List() case y :: ys => if(p(y)) (y :: filter(ys, p)) else filter(ys, p) }def evenF(xs: List[Int]) = filter[Int](xs, ((x: Int) => x % 2 == 0))def primes(xs: List[Int]) = filter[Int](xs, isPrime _)
  • scala> List(1, 2, 3, 4, 5) filter (_ % 2 == 0)res37: List[Int] = List(2, 4)scala> words filter (_.length == 3)res38: List[java.lang.String] = List(the, fox)scala> List(1, 2, 3, 4, 5) partition (_ % 2 == 0)res39: (List[Int], List[Int]) = (List(2, 4),List(1, 3, 5))scala> List(1, 2, 3, 4, 5) find (_ % 2 == 0)res40: Option[Int] = Some(2)scala> List(1, 2, 3, 4, 5) find (_ <= 0)res41: Option[Int] = None Filtering in Scala Libraryscala> List(1, 2, 3, 4,5) takeWhile (_ > 0)res42: List[Int] = List(1, 2, 3)scala> words dropWhile (_ startsWith "t")res43: List[java.lang.String] = List(quick, brown, fox)scala> List(1, 2, 3, 4,5) span (_ > 0)res44: (List[Int], List[Int]) = (List(1, 2, 3),List(4, 5)) xs partition p equals (xs filter p, xs filter (!p(_)))
  • def sum(xs: IntList): Int = xs match { case Nil() => 0 case Cons(y, ys) => y + sum(ys)}def product(xs: IntList): Int = xs match { case Nil() => 1 case Cons(y, ys) => y * product(ys)} Combining Elements
  • Factor out operatordef foldRight(xs: IntList, z: Int, op: (Int,Int)=>Int): Int = xs match { case Nil() => z case Cons(y, ys) => op(y, foldRight(ys, z, op)) }def sum(xs: IntList): Int = foldRight(xs, 0, (x: Int, y: Int) => x + y)def product(xs: IntList): Int = foldRight(xs, 1, (x: Int, y: Int) => x * y)
  • def foldLeft(xs: IntList, z: Int, op: (Int,Int) => Int): Int = xs match { case Nil() => z case Cons(y, ys) => foldLeft(ys, op(z, y), op) }def sumF(xs: IntList): Int = foldLeft(xs, 0, (x: Int, y: Int) => x + y) Tail recursive folding
  • Factor out typedef foldLeft[A,B](xs: List[A], z: B, op: (B,A) => B): B = xs match { case List() => z case y :: ys => foldLeft(ys, op(z, y), op) }
  • scala> ("" /: words) (_ +" "+ _) res46: java.lang.String = the quick brown fox scala> (words.head /: words.tail) (_ +" "+ _) res47: java.lang.String = the quick brown fox(z /: List(a, b, c)) (op)equalsop(op(op(z, a), b), c) Fold left in Scala LibraryList(a, b, c).foldLeft(z)(op)
  • sum(List(a, b, c)) equals 0 + a + b + cscala> def sum(xs: List[Int]): Int = (0 /: xs) (_ + _)sum: (List[Int])Int Folding Lists product(List(a, b, c)) equals 1 * a * b * c scala> def product(xs: List[Int]): Int = (1 /: xs) (_ * _) sum: (List[Int])Int
  • Fold Right(List(a, b, c) : z) (op)equalsop(a, op(b, op(c, z))) List(a, b, c).foldRight(z)(op)
  • Map defined with Fold def map[A,B](xs: List[A], f : A => B): List[B] = (xs : List[B]())( (x: A, ys: List[B]) => f(x) :: ys )Filter defined with Fold def filter[A](xs: List[A], p : A => Boolean): List[A] = (xs : List[A]())( (x: A, ys: List[A]) => if(p(x)) x :: ys else ys )
  • Re-occurring patterns• transform every element of a list• verify property of all elements of a list• extract elements satisfying some criterion• combining elements of a list using some operatorHigher-order functions• direct, reusable definitions of such patterns
  • Higher-order functions• reducing code duplication, simplifying client codeCurrying• partial function applicationsWriting new control structures• growing the languageBy-name parameters• lazy evaluation
  • Reading & Programming in Week 6Reading Sebesta Chapter 15: Functional Programming Languages Java Script TGP Chapter 4: FunctionsWebLab: C, JavaScript, Scala tutorials Graded Assignment 1: Dynamic Dispatch in C (deadline 2 April 2013, 23:59) Week 7: Polymorphism