SlideShare uma empresa Scribd logo
1 de 51
Baixar para ler offline
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 C

Important 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) was
an American mathematician and logician who made major
contributions to mathematical logic and the foundations of
theoretical computer science. He is best known for the
lambda calculus, Church–Turing thesis, proving the
undecidability of the Entscheidungsproblem, Frege–Church
ontology, and the Church–Rosser theorem.



The lambda calculus emerged in his famous 1936 paper showing the unsolvability of
the Entscheidungsproblem. This result preceded Alan Turing's famous work on the
halting problem, which also demonstrated the existence of a problem unsolvable by
mechanical means. Church and Turing then showed that the lambda calculus and the
Turing machine used in Turing's halting problem were equivalent in capabilities, and
subsequently demonstrated a variety of alternative "mechanical processes for
computation." This resulted in the Church–Turing thesis.
The lambda calculus influenced the design of the LISP programming language and
functional programming languages in general. The Church encoding is named in his
honor.


                 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 Calculus
Substitution
• 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 evaluation

Lambda calculus = essence of functional programming

instantiated in many modern programming languages
First-order functions

• Function definition              Functions are Values
• Function call
First-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 statements
Functional abstraction in Java

• methods
Functional 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 variable
var 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 base



incrementer =  base . (  x . (x + base))
inc3 = incrementer 3;
inc3 39



                                        In lambda notation
var scope = "global scope"; // A global variable      Closures
function 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 v
function 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 we're passing a single value
	   	   // and apply for g because we're 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 Objects
increase: (Int) => Int = <function1>

scala> increase(10)
res0: Int = 11

scala> increase = (x: Int) => x + 9999
increase: (Int) => Int = <function1>

scala> increase(10)
res1: Int = 10009

scala> 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
  operator
Higher-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 Library
res29: 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 Elements



def 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 Library
scala> 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 operator




def 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 type




def 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)

equals

op(op(op(z, a), b), c)               Fold left in Scala Library


List(a, b, c).foldLeft(z)(op)
sum(List(a, b, c))   equals   0 + a + b + c



scala> 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)

equals

op(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
  operator
Higher-order functions

• direct, reusable definitions of such patterns
Higher-order functions

• reducing code duplication, simplifying client code
Currying

• partial function applications
Writing new control structures

• growing the language
By-name parameters

• lazy evaluation
Reading & Programming in Week 6

Reading

  Sebesta Chapter 15: Functional Programming
  Languages

  Java Script TGP Chapter 4: Functions


WebLab:
  C, JavaScript, Scala tutorials
   Graded Assignment 1: Dynamic Dispatch in C
   (deadline 2 April 2013, 23:59)


                                    Week 7: Polymorphism

Mais conteúdo relacionado

Mais procurados

Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
stasimus
 
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
Fwdays
 

Mais procurados (20)

Clojure basics
Clojure basicsClojure basics
Clojure basics
 
Functional programming with haskell
Functional programming with haskellFunctional programming with haskell
Functional programming with haskell
 
Functional Programming in Javascript - IL Tech Talks week
Functional Programming in Javascript - IL Tech Talks weekFunctional Programming in Javascript - IL Tech Talks week
Functional Programming in Javascript - IL Tech Talks week
 
Lec2
Lec2Lec2
Lec2
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
 
Scala categorytheory
Scala categorytheoryScala categorytheory
Scala categorytheory
 
04. haskell handling
04. haskell handling04. haskell handling
04. haskell handling
 
The... Wonderful? World of Lambdas
The... Wonderful? World of LambdasThe... Wonderful? World of Lambdas
The... Wonderful? World of Lambdas
 
Lec3
Lec3Lec3
Lec3
 
The what over the how (another way on android development with kotlin)
The what over the how (another way on android development with kotlin)The what over the how (another way on android development with kotlin)
The what over the how (another way on android development with kotlin)
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
 
Object Equality in Scala
Object Equality in ScalaObject Equality in Scala
Object Equality in Scala
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
 
Lec2
Lec2Lec2
Lec2
 
The Ring programming language version 1.3 book - Part 25 of 88
The Ring programming language version 1.3 book - Part 25 of 88The Ring programming language version 1.3 book - Part 25 of 88
The Ring programming language version 1.3 book - Part 25 of 88
 
The Ring programming language version 1.5.1 book - Part 30 of 180
The Ring programming language version 1.5.1 book - Part 30 of 180The Ring programming language version 1.5.1 book - Part 30 of 180
The Ring programming language version 1.5.1 book - Part 30 of 180
 
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
 
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Left and Right Folds- Comparison of a mathematical definition and a programm...Left and Right Folds- Comparison of a mathematical definition and a programm...
Left and Right Folds - Comparison of a mathematical definition and a programm...
 
Humble introduction to category theory in haskell
Humble introduction to category theory in haskellHumble introduction to category theory in haskell
Humble introduction to category theory in haskell
 

Destaque (6)

Introduction to lambda expression & lambda calculus
Introduction to lambda expression & lambda calculusIntroduction to lambda expression & lambda calculus
Introduction to lambda expression & lambda calculus
 
Lambda calculus
Lambda calculusLambda calculus
Lambda calculus
 
The Lambda Calculus and The JavaScript
The Lambda Calculus and The JavaScriptThe Lambda Calculus and The JavaScript
The Lambda Calculus and The JavaScript
 
Lambda Calculus
Lambda CalculusLambda Calculus
Lambda Calculus
 
Residential_by_DeLaereDecor_Portfolio
Residential_by_DeLaereDecor_PortfolioResidential_by_DeLaereDecor_Portfolio
Residential_by_DeLaereDecor_Portfolio
 
Tensorflow in production with AWS Lambda
Tensorflow in production with AWS LambdaTensorflow in production with AWS Lambda
Tensorflow in production with AWS Lambda
 

Semelhante a TI1220 Lecture 6: First-class Functions

User defined functions
User defined functionsUser defined functions
User defined functions
shubham_jangid
 
Swift the implicit parts
Swift the implicit partsSwift the implicit parts
Swift the implicit parts
Maxim Zaks
 
Столпы функционального программирования для адептов ООП, Николай Мозговой
Столпы функционального программирования для адептов ООП, Николай МозговойСтолпы функционального программирования для адептов ООП, Николай Мозговой
Столпы функционального программирования для адептов ООП, Николай Мозговой
Sigma Software
 
Part 3-functions
Part 3-functionsPart 3-functions
Part 3-functions
ankita44
 

Semelhante a TI1220 Lecture 6: First-class Functions (20)

Composition birds-and-recursion
Composition birds-and-recursionComposition birds-and-recursion
Composition birds-and-recursion
 
Principles of functional progrmming in scala
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scala
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
User defined functions
User defined functionsUser defined functions
User defined functions
 
Thinking Functionally with JavaScript
Thinking Functionally with JavaScriptThinking Functionally with JavaScript
Thinking Functionally with JavaScript
 
Functions12
Functions12Functions12
Functions12
 
Functions123
Functions123 Functions123
Functions123
 
Monadologie
MonadologieMonadologie
Monadologie
 
Advanced JavaScript
Advanced JavaScript Advanced JavaScript
Advanced JavaScript
 
Why Haskell Matters
Why Haskell MattersWhy Haskell Matters
Why Haskell Matters
 
Functional Programming for OO Programmers (part 2)
Functional Programming for OO Programmers (part 2)Functional Programming for OO Programmers (part 2)
Functional Programming for OO Programmers (part 2)
 
Functional object
Functional objectFunctional object
Functional object
 
Swift the implicit parts
Swift the implicit partsSwift the implicit parts
Swift the implicit parts
 
Столпы функционального программирования для адептов ООП, Николай Мозговой
Столпы функционального программирования для адептов ООП, Николай МозговойСтолпы функционального программирования для адептов ООП, Николай Мозговой
Столпы функционального программирования для адептов ООП, Николай Мозговой
 
25-functions.ppt
25-functions.ppt25-functions.ppt
25-functions.ppt
 
Lecture 3
Lecture 3Lecture 3
Lecture 3
 
Functions in advanced programming
Functions in advanced programmingFunctions in advanced programming
Functions in advanced programming
 
Scala by Luc Duponcheel
Scala by Luc DuponcheelScala by Luc Duponcheel
Scala by Luc Duponcheel
 
Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0
 
Part 3-functions
Part 3-functionsPart 3-functions
Part 3-functions
 

Mais de Eelco Visser

Declarative Type System Specification with Statix
Declarative Type System Specification with StatixDeclarative Type System Specification with Statix
Declarative Type System Specification with Statix
Eelco Visser
 

Mais de Eelco Visser (20)

CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingCS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
 
CS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic ServicesCS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic Services
 
CS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | ParsingCS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | Parsing
 
CS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definitionCS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definition
 
CS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: IntroductionCS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: Introduction
 
A Direct Semantics of Declarative Disambiguation Rules
A Direct Semantics of Declarative Disambiguation RulesA Direct Semantics of Declarative Disambiguation Rules
A Direct Semantics of Declarative Disambiguation Rules
 
Declarative Type System Specification with Statix
Declarative Type System Specification with StatixDeclarative Type System Specification with Statix
Declarative Type System Specification with Statix
 
Compiler Construction | Lecture 17 | Beyond Compiler Construction
Compiler Construction | Lecture 17 | Beyond Compiler ConstructionCompiler Construction | Lecture 17 | Beyond Compiler Construction
Compiler Construction | Lecture 17 | Beyond Compiler Construction
 
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Domain Specific Languages for Parallel Graph AnalytiX (PGX)Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
 
Compiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory ManagementCompiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory Management
 
Compiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersCompiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | Interpreters
 
Compiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code GenerationCompiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code Generation
 
Compiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual MachinesCompiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual Machines
 
Compiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone FrameworksCompiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone Frameworks
 
Compiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 10 | Data-Flow AnalysisCompiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 10 | Data-Flow Analysis
 
Compiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint ResolutionCompiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint Resolution
 
Compiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type ConstraintsCompiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type Constraints
 
Compiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type CheckingCompiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type Checking
 
Compiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 6 | Introduction to Static AnalysisCompiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 6 | Introduction to Static Analysis
 
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term RewritingCompiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
 

TI1220 Lecture 6: First-class Functions

  • 1. Lecture 6: First-Class Functions TI1220 2012-2013 Concepts of Programming Languages Eelco Visser / TU Delft
  • 2.
  • 4. Graded Assignment 1 Algebraic datatypes in C Dynamic dispatch in C Important 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
  • 5. Alonzo Church (June 14, 1903 – August 11, 1995) was an American mathematician and logician who made major contributions to mathematical logic and the foundations of theoretical computer science. He is best known for the lambda calculus, Church–Turing thesis, proving the undecidability of the Entscheidungsproblem, Frege–Church ontology, and the Church–Rosser theorem. The lambda calculus emerged in his famous 1936 paper showing the unsolvability of the Entscheidungsproblem. This result preceded Alan Turing's famous work on the halting problem, which also demonstrated the existence of a problem unsolvable by mechanical means. Church and Turing then showed that the lambda calculus and the Turing machine used in Turing's halting problem were equivalent in capabilities, and subsequently demonstrated a variety of alternative "mechanical processes for computation." This resulted in the Church–Turing thesis. The lambda calculus influenced the design of the LISP programming language and functional programming languages in general. The Church encoding is named in his honor. http://en.wikipedia.org/wiki/Alonzo_Church
  • 6. Outline Lambda calculus First-class functions in JavaScript Functions as objects in Java First-class functions in Scala Generic, higher-order functions Control abstraction
  • 8. 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
  • 9. 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}
  • 10. Lambda Calculus Substitution • 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))
  • 11. What is the relevance of the lambda calculus?
  • 12. Lambda = first-class function Beta reduction = function evaluation Lambda calculus = essence of functional programming instantiated in many modern programming languages
  • 13. First-order functions • Function definition Functions are Values • Function call First-class functions • unnamed function literals (x: Int) => x + 1 • pass functions around as values: return as result, pass as parameter, store in data structure
  • 14. Code reuse • name and parameterize expressions and statements Functional abstraction in Java • methods Functional abstraction in Scala • nested functions • function literals • function values
  • 15. First-Class Functions in JavaScript
  • 16. // 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
  • 17. Anonymous Function Expressions // This function expression defines a function that squares its argument. // Note that we assign it to a variable var 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));
  • 18. var incrementer = Nested functions: Closures function (base) { return function (x) { return x + base; }; }; var inc3 = incrementer(3); inc3(39); remember value of base incrementer = base . ( x . (x + base)) inc3 = incrementer 3; inc3 39 In lambda notation
  • 19. var scope = "global scope"; // A global variable Closures function 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?
  • 20. 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
  • 21. // This function returns a function that always returns v function 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?
  • 22. function compose(f, g) { return function() { // We use call for f because we're passing a single value // and apply for g because we're 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
  • 23. 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]
  • 25. Does Java support first-class functions?
  • 26. 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
  • 28. Function Literals ((c: Int) => ((x: Int) => c+x))(1)(2) evaluation steps: - ((x: Int) => 1+x) (2) - 1+2 - 3
  • 29. scala> var increase = (x: Int) => x + 1 Function Values are Objects increase: (Int) => Int = <function1> scala> increase(10) res0: Int = 11 scala> increase = (x: Int) => x + 9999 increase: (Int) => Int = <function1> scala> increase(10) res1: Int = 10009 scala> increase.apply(10) res37: Int = 11 <function>(<args>) abbreviates <function>.apply(<args>)
  • 31. 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 operator Higher-order functions • direct, reusable definitions of such patterns
  • 32. 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
  • 33. 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))
  • 34. 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
  • 35. 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
  • 36. scala> List(1, 2, 3) map (_ + 1) Map in Scala Library res29: 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)
  • 37. 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) }
  • 38. 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
  • 39. Factor out Type of Elements def 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 _)
  • 40. 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 Library scala> 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(_)))
  • 41. 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
  • 42. Factor out operator def 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)
  • 43. 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
  • 44. Factor out type def 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) }
  • 45. 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) equals op(op(op(z, a), b), c) Fold left in Scala Library List(a, b, c).foldLeft(z)(op)
  • 46. sum(List(a, b, c)) equals 0 + a + b + c scala> 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
  • 47. Fold Right (List(a, b, c) : z) (op) equals op(a, op(b, op(c, z))) List(a, b, c).foldRight(z)(op)
  • 48. 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 )
  • 49. 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 operator Higher-order functions • direct, reusable definitions of such patterns
  • 50. Higher-order functions • reducing code duplication, simplifying client code Currying • partial function applications Writing new control structures • growing the language By-name parameters • lazy evaluation
  • 51. Reading & Programming in Week 6 Reading Sebesta Chapter 15: Functional Programming Languages Java Script TGP Chapter 4: Functions WebLab: C, JavaScript, Scala tutorials Graded Assignment 1: Dynamic Dispatch in C (deadline 2 April 2013, 23:59) Week 7: Polymorphism