Chapter 7: Functional Programming Languages

Save this PDF as:

Size: px
Start display at page:

Transcription

1 Chapter 7: Functional Programming Languages Aarne Ranta Slides for the book Implementing Programming Languages. An Introduction to Compilers and Interpreters, College Publications, 2012.

2 Fun: a language that is much simpler but in many ways more powerful than an imperative language. A fragment of Haskell, with a grammar that has less than 15 rules. But there are conceptual challenges recursion call by name closures polymorphic type inference Concepts and tools needed for Assignment 5.

3 Programming paradigms Imperative, a.k.a. procedural: a program is a series of statements that affect a state. Functional: a program is just an expression. executing a program is just evaluation no state is needed But also imperative programs evaluate expressions. Thus functional programming only uses a subset of what imperative programs use.

4 Example of a functional program In Haskell, and also in Assignment 5: doub x = x + x ; twice f x = f (f x) ; quadruple = twice doub ; main = twice quadruple 2 ; A program is a sequence of function definitions. main prints an integer (in Haskell, it is more general).

5 The syntax of function applications Haskell: just put the function and its arguments one after the other, f x y z C (and ordinary mathematics), use parentheses and commas, f(x, y, z)

6 Walk through the computation of main main = twice quadruple 2 = quadruple (quadruple 2) = twice doub (twice doub 2) = doub (doub (doub (doub 2))) = doub (doub (doub (2 + 2))) = doub (doub (doub 4)) = doub (doub (4 + 4)) = doub (doub 8) = doub (8 + 8) = doub 16 = = 32 At each step, we replace some part of the expression by its definition, or variables by their actual arguments. The replacement operation is called substitution.

7 First-order functions The doub function can be defined in C and Java as well: // doub x = x + x int doub (int x) { return x + x ; } But this mechanism is restricted to what is called first-order functions: the arguments cannot themselves be functions.

8 Second-order functions Possible in C++ (as in Haskell): take functions as arguments, as the twice function does // twice f x = f (f x) int twice(int f (int n), int x) { return f(f(x)) ; }

9 Functions as values In a functional language, functions are first-class citizens, just like numbers: function expressions have values even without arguments functions can be arguments of functions functions can be return values In C++, a function cannot be a return value: // quadruple = twice doub // not possible in V++: (int f (int x)) quadruple() { return twice(doub) ; }

10 We must pass an additional argument, which enables quadruple to return an integer and not a function: int quadruple(int x) { return twice(doub, x) ; } This corresponds to another definition in Haskell: quadruple x = twice doub x This definition has the same meaning as the one without x.

11 Function types We write a two-place integer functionmax max : Int -> Int -> Int (Haskell uses a double colon :: for typing, but we stick to a single :.) The notation is right-associative, and hence equivalent to max : Int -> (Int -> Int) The typing rule for function applications is: Γ f : A B Γ a : A Γ f a : B

12 Partial application The typing rule permits max 4 : Int -> Int This is a function that returns the maximum of its argument and 4. Notice Application is left-associative: max 4 5 is the same as (max 4) 5.

13 The tuple type One could also force total application by using a tuple of arguments: maxt : (Int * Int) -> Int Tuples are a type of its own, with the following typing rule: Γ a : A Γ b : B Γ (a, b) : A*B

14 Currying An equivalence between functions over tuples and two-place functions: (A B) C A B C Converting the first to the second is called currying, with reference to Haskell B. Curry. Currying simplifies the semantics and implementation of programming languages: it is enough to work with one-place functions!

15 Anonymous functions In imperative languages, functions must be explicitly defined and given names. In a functional language, any expression can be turned into ananonymous functions, by lambda abstraction: timesnine = twice (\x -> x + x + x) Syntactically, a lambda abstract is an expression λx.e (using λ instead of \). The typing rule for lambda abstracts. Γ, x : A e : B Γ λx.e : A B

16 Function definitions as syntactic sugar It is enough to have definitions of constance, because a function definition f x 1... x n = e can be expressed as the definition of a constant as a lambda abstract, f = λx λx n.e Also this simplifies the implementation: the environment need only map identifiers to types (in the type checker) or values (in the interpreter).

17 As C++ has no anonymous functions, we cannot write timesnine directly, but have to define a named tripling function first: // triple x = x + x + x int triple(int x) { return x + x + x ; } // timesnine = twice triple int timesnine(int x) { return twice(triple, x) ; } But there is an experimental Lambda Library in C++ permitting anonymous functions.

18 Our language We can start with only four expression forms: Exp ::= Ident -- variables, constants Integer -- integer literals "(" "\" Ident "->" Exp ")" -- abstractions "(" Exp Exp ")" -- applications

19 Operational semantics Judgements of the usual form, γ e v read, in the environment γ, the expression e evaluates to the value v. Notice that evaluation cannot change the environment! Thus we have a purely functional language, a language without side effects. The environment is a set of values assigned to variables, x := v, y := w,...

20 Values We need to be more general now, because we need function as values. The simplest view: values are expressions evaluation converts an expression to another expression evaluation stops when it cannot proceed further The resulting expression is often simpler, as in But it can also be more complex, as in replicate 20 1 [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]

21 What is a value * 8 is not a value, because the evaluation can proceed can be more interesting a value than as an answer, because it is more informative * x is a value, in the sense that we cannot take it any further, because known what x is. In another sense, it isn t: we were expecting to get a number, but we don t have one yet. We must first give a value to x and then perform multiplication and addition.

22 Free variables A value may not contain free variables, which could get any values. Bound variables are different. They are the ones appearing in lambda bindings. The precise definition of the set free, free variables of an expression: free(x) = {x} free(i) = {} free(f a) = free(f) free(a) free(λx.b) = free(b) {x} An expression that has no free variables (i.e. free(e) = {}) is a closed expression. An expression that does have free variables is an open expression.

23 Closures Notice: the closed expressions are those where all variables are bound by lambdas. Special case: expressions with no variables. Approximation of values: closed expressions. In addition to lambda, it makes sense to close an expression by just giving values of its free variables. For instance, (2 + 3 * x){x := 8} The general form: a closure is an expression e with an environmen γ: e{γ}

24 Values revisited We will use two kinds of values: integers closures of lambda abstracts Special case: closed lambda abstract (with an empty closure).

25 Operational semantics Variables: Integer literals: γ x v x := v is in γ γ i i Lambda abstracts: γ (λx.e) (λx.e){γ} Function applications: γ f (λx.e){δ} γ a u δ, x := u e v γ (f a) v (That s all!)

26 Some explanations Abstractions: the body of the lambda abstract may contain variables than the one bound by the lambda. These variables get their values in the environment. Applications: this comes out as a modification of the imperative rule in Chapter 5, γ a u Modifications: x := u s 1... s n v γ f(a) v if V f(t x){s 1... s n } in γ now enough to consider functions with one argument evaluation has no side effects now the function body: in the imperative language, it is a sequence of statements, s 1... s n ; in the functional language, it is a lambda abstraction body e, which is an expression.

27 the function f: in the imperative language, it is always an explicitly defined function symbol; in the functional language, it can be any expression (for instance, a lambda abstract or an application). Thus the evaluation of f is not simply a look-up in the function table. But we can just replace the look-up by a step of evaluating the expression f. This evaluation results in a closure, with a lambda abstract λx.e and an environment δ. Then (f a) is computed by evaluating e in an environment where the variable x is set to the value of the argument a.

28 Example Assume the function definition doub x = x + x which means the same as doub = \x -> x + x Compute doub 4 as follows: doub (λx.x + x){} 4 4 x := 4 x + x 8 (doub 4) 8 The applied function has no free variables. But this is just a limiting case.

29 Example showing the need of closures A two-place function, plus x y = x + y Evaluation of the expression plus 3 4 (i.e. ((plus 3) 4)): plus (λx.λy.x + y){} 3 3 x := 3 (λy.x + y) (λy.x + y){x := 3} (plus 3) (λy.x + y){x := 3} 4 4 x := 3, y := 4 x + y 7 ((plus 3) 4) 7

30 Call by value vs. call by name Call by value: evaluate the argument first, then the body (as above): γ f (λx.e){δ} γ a u δ, x := u e v γ (f a) v Call by name: the body with unevaluated argument: γ f (λx e){δ} γ (f a) v δ, x := a{γ} e v Notice that γ is the proper way to close the expression a, because it is the environment in which a would be evaluated if we were performing call by value.

31 Examples The difference is enorbous! Consider infinite = 1 + infinite first x y = x main = first 5 infinite With call by value, main = first 5 infinite = (\x -> \y -> x) 5 (1 + infinite) = (\y -> 5) (1 + infinite) = (\y -> 5) (2 + infinite)... which leads to non-termination. Even though the function first ignores its second argument, call-by-value requires this argument to be evaluated.

32 With call by name, main = first 5 infinite = (\x -> \y -> x) 5 infinite = (\y -> 5) infinite = 5 There is no attempt to evaluate the second argument, because it is not needed by first. Call-by-value and call-by-name are just two possible orders. But callby-name has the property that it is the most terminating one: if there is any order that makes the evaluation of an expression terminate, then call-by-name is such an order.

33 Disadvantages of call by name It may lead to some expressions getting evaluated many times: once for each time the argument is used. Example: doub x = x + x doub (doub 8) = doub 8 + doub 8 -- by name = = 32 doub (doub 8) = doub by value = = 32

34 Call by need An intermediate strategy, used in Haskell. As in call by name, the expression is not evaluated when it is put to the environment. But when the value is needed for the first time, the result of evaluation is saved in the environment, and the next look-up of the variable will not need to compute it again. To make this possible, evaluation changes the environment - just like in imperative languages.

35 Implementing an interpreter: the language An extended language with two primitive forms of expressions: operations and if-then-else. infix Exp3 ::= Ident Exp3 ::= Integer Exp2 ::= Exp2 Exp3 Exp1 ::= Exp1 "+" Exp2 Exp1 ::= Exp1 "-" Exp2 Exp1 ::= Exp1 "<" Exp2 Exp ::= "if" Exp1 "then" Exp1 "else" Exp Exp ::= "\\" Ident "->" Exp A program is a sequence of function definitions, each of which has the form f x 1... x n = e ;

36 An example program The function pow defines powers of 2 by recursion. doub x = x + x ; pow x = if (x < 1) then 1 else doub (pow (x-1)) ; main = pow 30 ;

37 Execution of programs Evaluate the expression main. Environment: all functions mapped to their definitions. Each definition looks like a closure, with an empty environment. For instance, the example program above creates the following environment: doub := (\x -> x + x){} pow := (\x -> if (x < 1) then 1 else doub (pow (x-1))){} main := (pow 30){} Notice the empty environments {} in the values (closures) of each function. (Putting the function definitions in these environments would be impossible: just try this with the recursive function pow!)

38 Operations on environments Val lookup (Ident x, Env γ) Env update (Env γ, Ident x, Val v) The lookup function has to implement the overshadowing of identifiers: a variable overshadows a function symbol; an inner variable overshadows an outer variable. The latter follows from the simple rule that, in λx e, the free occurrences of x get bound in e.

39 Quiz: what is the value of (\x -> \x -> x + x) 2 3

40 Answer: in the expression \x -> \x -> x + x it is the second lambda that binds both variables in x + x. We get (\x -> \x -> x + x) 2 3 = ((\x -> x + x){x := 2}) 3 = (\x -> x + x) 3 = = 6

41 Syntax-directed interpreter code Integer literal: eval(γ, i) : return i Alternatively, we can return i{}, if we uniformly want closures as values. Variable expressions: eval(γ, x) : e{δ} := lookup(γ, x) eval( functions(γ), δ, e) We split the environment into a pair functions, variables, with separate storage for functions and variables.

42 Arithmetic operations: reduced to integer operations in the implementation language: eval(γ, a + b) : u := eval(γ, a) v := eval(γ, b) return u + v < has a similar rule, returning 1 if the comparison is true, 0 if it is false.

43 Conditionals: strategy: interpreted lazily, even if call by value is the general eval(γ, if c then a else b) : u := eval(γ, c) if u = 1 eval(γ, a) else eval(γ, b)

44 Abstractions: return closures with the variables of the current environment, eval(γ, λx.b) : return (λx.b){variables(γ)} Notice that we take only the variables of the environment into the closure, not the function symbols.

45 Application is the most complex case. A general rule for both call by value and call by name. The decision is made in just one point: when deciding what value to use for the bound variable when evaluating the body. eval(γ, (f a)) : (λx.b){δ} := eval(γ, f) if call by value u := eval(γ, a) else u := a{variables(γ)} eval(update( functions(γ), δ, x, u), b)

46 Implementing an interpreter Less than 100 lines of Haskell code or a little more Java code. The interpreter can be made parametrized on evaluation strategy, which is passed as a flag when the interpreter is called.

47 Type checking functional languages* Our language has a type system known as the simply typed lambda calculus. Two kinds of types: basic types, such as int; function types A B, where A and B are types. The power comes from the unconstrained generation of function types from any other types: int -> int (int -> int) -> int int -> (int -> int) ((int -> int) -> int) -> int

48 Type checking Abstraction rule: Type checking is easy: Γ, x : A b : B Γ λx.b : A B check(γ, λx.b, A B) : check(extend(γ, x, A), b, B)

49 Type inference But what about type inference? Example: \x -> x has infinitely many types: int -> int (int -> int) -> (int -> int) (int -> int -> int) -> (int -> int -> int) In fact, it has all types of the form A -> A Hence it is impossible to do type inference for all expressions - if we expect a unique type.

50 Typed abstraction One way to solve the type inference problem is to include type information in syntax: λx : t.b

51 Polymorphism* But a more common solution is a polymorphic type system: one and the same expression can have many types, usually depending on a type variable. Introduced in ML in the 1970 s, inherited by Haskell in the 1990 s. Inspired the template system C and the generics of Java.

52 Templates and generics Simplest possible example: the identity function, in C++ // id : A -> A, id = \x -> x template<class A> A id(a x) { return x ; } and in Java // id : A -> A, id = \x -> x public static <A> A id(a x) { return x ; } In both cases, A is a type variable. (C++ and Java use capital letters, Haskell uses small letters.)

53 The most general type In C++ and Java, calls to polymorphic functions must indicate the actual types. This makes type inference easy. In ML and Haskell, this is not required. But type inference works even then! Hindley-Milner polymorphism has an algorithm that computes the most general type. Examples: (\x -> x) : a -> a (\x -> \y -> x) : a -> b -> a (\f -> \x -> f (f x)) : (a -> a) -> a -> a (\x -> x + x) : int -> int Notice: different variables mean more generality than the same variable. For example, a -> b is more general than a -> a.

54 How to infer the most general type Start by introducing a variable t for the type of the expression: (\f -> \x -> f (f x)) : t Since the expression is a double abstraction, t must be a function type: t = a -> b -> c The body of the expression must of course obey this type: f (f x) : c Since f is used as a function here, it must have a function type: f : d -> e

55 But since f is the variable bound by the first lambda, we also have f : a and hence, a = d -> e Thus the result of applying f must have type e. But it must also have type c, because f (f x) : c. What is more, it must also have type d, because f can be applied to its own result. Hence c = e = d The type of x is on one hand b (as the second abstracted variable), on the other hand d (because f applies to x). Hence

56 c = e = b = d and, since a = d -> e, a = d -> d We can now conclude with t = (d -> d) -> d -> d as the most general type.

57 Mechanizing type inference The procedure above was completely heuristic - a little bit like solving a Sudoku. But there is a mechanical algorithm, using unification - a general method for solving a set of equations. Unification takes two types (with variables) and returns a substitution, mapping type variables to types. We will define the main type inference Subst, Type infer (Exp e) and the auxiliary function finding most general unifier, Subst mgu (Type t, Type u)

58 Substitution vs. context Substitution: type variables to types. Context: expression variables to types (as in Chapter 4). We will keep the context implicit in the pseudocode, accessible by the functions Type lookup (Ident x) // look up type of variable in context Void extend (Ident x, Type t) // put new variable to context Void free (Ident x) // remove variable from context We also need, in the course of type inference Ident fresh () // generate a new type variable

59 Applying a substitution to a type We write tγ for applying γ to t, which means replacing the type variables in t with their values given in γ. Example: (a -> c -> d){a:= d -> d, c:=d, b:=d} (d -> d) -> d -> d (applied at one point in the type inference example above)

60 Code for type inference Constants and variables are simple, and return the empty substitution {}: infer (i) : return {}, Int infer (x) : t := lookup(x) return {}, t

61 Lambda abstracts: infer (λx.b) : a := fresh() // variable for the type of x extend(x, a) γ, t := infer (b) // infer the type of the body free(x) // the new variable no more in scope return γ, aγ t Application: two slides later.

62 Example We can now infer the type of the identity function mechanically: infer (λx.x) : a := fresh() extend(x, a) {}, a := infer (x) // in context x : a return {}, a{} a By applying the empty substitution, we get the final type a a.

63 Type inference for function application infer (f a) : γ 1, t 1 := infer (f) // infer type of function γ 2, t 2 := infer (a) // infer type of argument v := fresh() // variable for the return type γ 3 := mgu(t 1 γ 2, t 2 v) // combine information return γ 3 γ 2 γ 1, vγ 3 All information is finally gathered in the composition of substitutions γ 3 γ 2 γ 1. Similar to the usual composition of functions: t(δ γ) = (tγ)δ

64 Defining unification The function mgu takes two types and returns their most general unifier. This is a substitution γ that gives the same result when applied to any of the two types: t(mgu(t, u)) = u(mgu(t, u)) Of course, mgu can also fail, if the types are not unifiable. Unification is defined by pattern matching on the type.

65 Subst mgu (Type t, Type u) mgu(a 1 b 1, a 2 b 2 ) : // both are function types γ 1 := mgu(a 1, a 2 ) γ 2 := mgu(b 1 γ 1, b 2 γ 1 ) return γ 2 γ 1 mgu(v, t) : // the first type is a type variable if t = v return {} else if occurs(v, t) fail ( occurs check ) else return {v := t} mgu(t, v) : // the second type is a type variable mgu(v, t) mgu(t, u) : // other cases: succeeds only for equal types if t = u return {} else fail ( types not unifiable )

66 When does unification fail? 1. If the types are syntactically different, e.g. Int vs. Double Int vs. a -> b 2. By occurs check: if the type variable v occurs in the type t, then t and v are not unifiable. v vs. v u Without occurs check, we would get {v := v u} which would need an infinite type (... (v u)... u) u

67 Another example Type inference for function applications, with occurs check: infer (λx.(x x)) : a := fresh() γ, t := infer (x x) : // in context x : a {}, a := infer (x) {}, a := infer (x) b := fresh() γ := mgu(a, a b) : fail ( occurs check ) On the last line, mgu fails because of occurs check: a cannot unify with a b.

68 Self-application A function cannot be applied to itself: occurs check blocks \x -> (x x) Quiz: however, a self-application is completely legal in (\x -> x)(\x -> x) Can you explain why?

Compiler Design. Type Checking

Compiler Design Type Checking Static Checking Token Stream Parser Abstract Syntax Tree Static Checker Decorated Abstract Syntax Tree Intermediate Code Generator Intermediate Code Static (Semantic) Checks

Functional Programming

FP 2005 1.1 3 Functional Programming WOLFRAM KAHL kahl@mcmaster.ca Department of Computing and Software McMaster University FP 2005 1.2 4 What Kinds of Programming Languages are There? Imperative telling

Programming Language Features (cont.) CMSC 330: Organization of Programming Languages. Parameter Passing in OCaml. Call-by-Value

CMSC 33: Organization of Programming Languages Programming Language Features (cont.) Names & binding Namespaces Static (lexical) scopes Dynamic scopes Polymorphism Parametric Subtype Ad-hoc Parameter Passing

Functional Programming. Functional Programming Languages. Chapter 14. Introduction

Functional Programming Languages Chapter 14 Introduction Functional programming paradigm History Features and concepts Examples: Lisp ML 1 2 Functional Programming Functional Programming Languages The

Type Classes with Functional Dependencies

Appears in Proceedings of the 9th European Symposium on Programming, ESOP 2000, Berlin, Germany, March 2000, Springer-Verlag LNCS 1782. Type Classes with Functional Dependencies Mark P. Jones Department

Chapter 15 Functional Programming Languages

Chapter 15 Functional Programming Languages Introduction - The design of the imperative languages is based directly on the von Neumann architecture Efficiency (at least at first) is the primary concern,

+ addition - subtraction and unary minus * multiplication / division mod modulo

Chapter 4 Basic types We examine in this chapter the Caml basic types. 4.1 Numbers Caml Light provides two numeric types: integers (type int) and floating-point numbers (type float). Integers are limited

Journal of Functional Programming, volume 3 number 4, 1993. Dynamics in ML

Journal of Functional Programming, volume 3 number 4, 1993. Dynamics in ML Xavier Leroy École Normale Supérieure Michel Mauny INRIA Rocquencourt Abstract Objects with dynamic types allow the integration

Overview. Elements of Programming Languages. Advanced constructs. Motivating inner class example

Overview Elements of Programming Languages Lecture 12: Object-oriented functional programming James Cheney University of Edinburgh November 6, 2015 We ve now covered: basics of functional and imperative

Programming Languages in Artificial Intelligence

Programming Languages in Artificial Intelligence Günter Neumann, German Research Center for Artificial Intelligence (LT Lab, DFKI) I. AI programming languages II. Functional programming III. Functional

CMCS 312: Programming Languages Lecture 3: Lambda Calculus (Syntax, Substitution, Beta Reduction) Acar & Ahmed 17 January 2008

CMCS 312: Programming Languages Lecture 3: Lambda Calculus (Syntax, Substitution, Beta Reduction) Acar & Ahmed 17 January 2008 Contents 1 Announcements 1 2 Introduction 1 3 Abstract Syntax 1 4 Bound and

Anatomy of Programming Languages. William R. Cook

Anatomy of Programming Languages William R. Cook Copyright (C) 2013 2 Chapter 1 Preliminaries Preface What? This document is a series of notes about programming languages, originally written for students

Semester Review. CSC 301, Fall 2015

Semester Review CSC 301, Fall 2015 Programming Language Classes There are many different programming language classes, but four classes or paradigms stand out:! Imperative Languages! assignment and iteration!

The PCAT Programming Language Reference Manual

The PCAT Programming Language Reference Manual Andrew Tolmach and Jingke Li Dept. of Computer Science Portland State University (revised October 8, 2004) 1 Introduction The PCAT language (Pascal Clone

Moving from CS 61A Scheme to CS 61B Java

Moving from CS 61A Scheme to CS 61B Java Introduction Java is an object-oriented language. This document describes some of the differences between object-oriented programming in Scheme (which we hope you

Object Oriented Software Design

Object Oriented Software Design Introduction to Java - II Giuseppe Lipari http://retis.sssup.it/~lipari Scuola Superiore Sant Anna Pisa October 28, 2010 G. Lipari (Scuola Superiore Sant Anna) Introduction

Programming Language Rankings. Lecture 15: Type Inference, polymorphism & Type Classes. Top Combined. Tiobe Index. CSC 131! Fall, 2014!

Programming Language Rankings Lecture 15: Type Inference, polymorphism & Type Classes CSC 131 Fall, 2014 Kim Bruce Top Combined Tiobe Index 1. JavaScript (+1) 2. Java (-1) 3. PHP 4. C# (+2) 5. Python (-1)

ML for the Working Programmer

ML for the Working Programmer 2nd edition Lawrence C. Paulson University of Cambridge CAMBRIDGE UNIVERSITY PRESS CONTENTS Preface to the Second Edition Preface xiii xv 1 Standard ML 1 Functional Programming

Computer Programming I

Computer Programming I COP 2210 Syllabus Spring Semester 2012 Instructor: Greg Shaw Office: ECS 313 (Engineering and Computer Science Bldg) Office Hours: Tuesday: 2:50 4:50, 7:45 8:30 Thursday: 2:50 4:50,

Object Oriented Software Design

Object Oriented Software Design Introduction to Java - II Giuseppe Lipari http://retis.sssup.it/~lipari Scuola Superiore Sant Anna Pisa September 14, 2011 G. Lipari (Scuola Superiore Sant Anna) Introduction

[Refer Slide Time: 05:10]

Principles of Programming Languages Prof: S. Arun Kumar Department of Computer Science and Engineering Indian Institute of Technology Delhi Lecture no 7 Lecture Title: Syntactic Classes Welcome to lecture

CS 141: Introduction to (Java) Programming: Exam 1 Jenny Orr Willamette University Fall 2013

Oct 4, 2013, p 1 Name: CS 141: Introduction to (Java) Programming: Exam 1 Jenny Orr Willamette University Fall 2013 1. (max 18) 4. (max 16) 2. (max 12) 5. (max 12) 3. (max 24) 6. (max 18) Total: (max 100)

The countdown problem

JFP 12 (6): 609 616, November 2002. c 2002 Cambridge University Press DOI: 10.1017/S0956796801004300 Printed in the United Kingdom 609 F U N C T I O N A L P E A R L The countdown problem GRAHAM HUTTON

1 Introduction. 2 An Interpreter. 2.1 Handling Source Code

1 Introduction The purpose of this assignment is to write an interpreter for a small subset of the Lisp programming language. The interpreter should be able to perform simple arithmetic and comparisons

Static vs. Dynamic. Lecture 10: Static Semantics Overview 1. Typical Semantic Errors: Java, C++ Typical Tasks of the Semantic Analyzer

Lecture 10: Static Semantics Overview 1 Lexical analysis Produces tokens Detects & eliminates illegal tokens Parsing Produces trees Detects & eliminates ill-formed parse trees Static semantic analysis

Busy Java Developer's Guide to Functional Programming. Ted Neward Neward & Associates http://www.tedneward.com

Busy Java Developer's Guide to Functional Programming Ted Neward Neward & Associates http://www.tedneward.com Who is this guy? Principal Consultant: architect, mentor, free agent coach BEA Technical Director,

Type Systems. Luca Cardelli. Microsoft Research

Type Systems Luca Cardelli Microsoft Research 1 Introduction The fundamental purpose of a type system is to prevent the occurrence of execution errors during the running of a program. This informal statement

Rigorous Software Development CSCI-GA 3033-009

Rigorous Software Development CSCI-GA 3033-009 Instructor: Thomas Wies Spring 2013 Lecture 11 Semantics of Programming Languages Denotational Semantics Meaning of a program is defined as the mathematical

1.1 WHAT IS A PROGRAMMING LANGUAGE?

1 INTRODUCTION 1.1 What is a Programming Language? 1.2 Abstractions in Programming Languages 1.3 Computational Paradigms 1.4 Language Definition 1.5 Language Translation 1.6 Language Design How we communicate

Regression Verification: Status Report

Regression Verification: Status Report Presentation by Dennis Felsing within the Projektgruppe Formale Methoden der Softwareentwicklung 2013-12-11 1/22 Introduction How to prevent regressions in software

Review. Abstract Interpretation. Part II. Lecture 19. Notes (Cont.) Review: Calculating the LFP

Review Abstract Interpretation Part II def f(x) = if x = 0 then 1 else x f(x + -1) Abstraction: ( σ ʹ ( = + )) lfp if x 0 then 1 else x f(x -1) Simplified: ( λ λ + ( + )) lfp f. x. x f(x ) 1 2 Review:

Why? A central concept in Computer Science. Algorithms are ubiquitous.

Analysis of Algorithms: A Brief Introduction Why? A central concept in Computer Science. Algorithms are ubiquitous. Using the Internet (sending email, transferring files, use of search engines, online

Chapter 5 Names, Bindings, Type Checking, and Scopes

Chapter 5 Names, Bindings, Type Checking, and Scopes Chapter 5 Topics Introduction Names Variables The Concept of Binding Type Checking Strong Typing Scope Scope and Lifetime Referencing Environments Named

Programming Languages CIS 443

Course Objectives Programming Languages CIS 443 0.1 Lexical analysis Syntax Semantics Functional programming Variable lifetime and scoping Parameter passing Object-oriented programming Continuations Exception

Type Systems. Luca Cardelli. Digital Equipment Corporation Systems Research Center

Type Systems 1 Introduction Luca Cardelli Digital Equipment Corporation Systems Research Center The fundamental purpose of a type system is to prevent the occurrence of execution errors during the running

Software Analysis (POPA Sec , )

Software Analysis (POPA Sec. 2.2.2, 2.5-2.5.2) Klaus Ostermann Based on slides by Jurriaan Hage Overview Correctness proof Live Variables Analysis The While language with procedures Live Variables Analysis

Programming Language Pragmatics

Programming Language Pragmatics THIRD EDITION Michael L. Scott Department of Computer Science University of Rochester ^ШШШШШ AMSTERDAM BOSTON HEIDELBERG LONDON, '-*i» ЩЛ< ^ ' m H NEW YORK «OXFORD «PARIS»SAN

Deterministic Discrete Modeling

Deterministic Discrete Modeling Formal Semantics of Firewalls in Isabelle/HOL Cornelius Diekmann, M.Sc. Dr. Heiko Niedermayer Prof. Dr.-Ing. Georg Carle Lehrstuhl für Netzarchitekturen und Netzdienste

Higher-Order Logic. Specification and Verification with Higher-Order Logic

Higher-Order Logic Specification and Verification with Higher-Order Logic Arnd Poetzsch-Heffter Software Technology Group Fachbereich Informatik Technische Universität Kaiserslautern Sommersemester 2010

Programming Languages

Programming Languages Jörg Kreiker Chair for Theoretical Computer Science Prof. Esparza TU München winter term 2010/2011 3 Lecture 7 Continuations 4 Continuations why? Goal 2: To use language features

6.087 Lecture 3 January 13, 2010

6.087 Lecture 3 January 13, 2010 Review Blocks and Compound Statements Control Flow Conditional Statements Loops Functions Modular Programming Variable Scope Static Variables Register Variables 1 Review:

Semantic Analysis: Types and Type Checking

Semantic Analysis Semantic Analysis: Types and Type Checking CS 471 October 10, 2007 Source code Lexical Analysis tokens Syntactic Analysis AST Semantic Analysis AST Intermediate Code Gen lexical errors

Functional Programming in C++11

Functional Programming in C++11 science + computing ag IT-Dienstleistungen und Software für anspruchsvolle Rechnernetze Tübingen München Berlin Düsseldorf An Overview Programming in a functional style

Regular Expressions and Automata using Haskell

Regular Expressions and Automata using Haskell Simon Thompson Computing Laboratory University of Kent at Canterbury January 2000 Contents 1 Introduction 2 2 Regular Expressions 2 3 Matching regular expressions

Observational Program Calculi and the Correctness of Translations

Observational Program Calculi and the Correctness of Translations Manfred Schmidt-Schauss 1, David Sabel 1, Joachim Niehren 2, and Jan Schwinghammer 1 Goethe-University, Frankfurt, Germany 2 INRIA Lille,

Object-Oriented Software Specification in Programming Language Design and Implementation

Object-Oriented Software Specification in Programming Language Design and Implementation Barrett R. Bryant and Viswanathan Vaidyanathan Department of Computer and Information Sciences University of Alabama

Integrating Formal Models into the Programming Languages Course

Integrating Formal Models into the Programming Languages Course Allen B. Tucker Robert E. Noonan Computer Science Department Computer Science Department Bowdoin College College of William and Mary Brunswick,

Semantics and Verification of Software

Semantics and Verification of Software Lecture 21: Nondeterminism and Parallelism IV (Equivalence of CCS Processes & Wrap-Up) Thomas Noll Lehrstuhl für Informatik 2 (Software Modeling and Verification)

A Scala Tutorial for Java programmers

A Scala Tutorial for Java programmers Version 1.3 January 16, 2014 Michel Schinz, Philipp Haller PROGRAMMING METHODS LABORATORY EPFL SWITZERLAND 2 1 Introduction This document gives a quick introduction

Improving type-error messages in functional languages

Improving type-error messages in Bastiaan Heeren Universiteit Utrecht January 5, 200 Contents Introduction Constraints Type inference rules Solving constraints Solving inconsistencies Future work Conclusion

Predicate logic is an Extension of sentence logic. Several new vocabulary items are found in predicate logic.

Atomic Sentences of Predicate Logic Predicate Logic and Sentence Logic Predicate logic is an Extension of sentence logic. All items of the vocabulary of sentence logic are items of the vocabulary of predicate

The Needle Programming Language

The Needle Programming Language The Needle Programming Language 1 What is Needle? Needle is an object-oriented functional programming language with a multimethod-based OO system, and a static type system

1 Operational Semantics for While

Models of Computation, 2010 1 1 Operational Semantics for While The language While of simple while programs has a grammar consisting of three syntactic categories: numeric expressions, which represent

Algebraic expansion and simplification

Chapter 3 Algebraic expansion and simplification Contents: A Collecting like terms B Product notation C The distributive law D The product (a + b)(c + d) E Difference of two squares F Perfect squares expansion

Lexical analysis FORMAL LANGUAGES AND COMPILERS. Floriano Scioscia. Formal Languages and Compilers A.Y. 2015/2016

Master s Degree Course in Computer Engineering Formal Languages FORMAL LANGUAGES AND COMPILERS Lexical analysis Floriano Scioscia 1 Introductive terminological distinction Lexical string or lexeme = meaningful

(LMCS, p. 317) V.1. First Order Logic. This is the most powerful, most expressive logic that we will examine.

(LMCS, p. 317) V.1 First Order Logic This is the most powerful, most expressive logic that we will examine. Our version of first-order logic will use the following symbols: variables connectives (,,,,

Organization of Programming Languages CS320/520N. Lecture 05. Razvan C. Bunescu School of Electrical Engineering and Computer Science bunescu@ohio.

Organization of Programming Languages CS320/520N Razvan C. Bunescu School of Electrical Engineering and Computer Science bunescu@ohio.edu Names, Bindings, and Scopes A name is a symbolic identifier used

Chapter 6: Programming Languages

Chapter 6: Programming Languages Computer Science: An Overview Eleventh Edition by J. Glenn Brookshear Copyright 2012 Pearson Education, Inc. Chapter 6: Programming Languages 6.1 Historical Perspective

The programming language C. sws1 1

The programming language C sws1 1 The programming language C invented by Dennis Ritchie in early 1970s who used it to write the first Hello World program C was used to write UNIX Standardised as K&C (Kernighan

Group number 24 Joni Saarinen Daniel Kullberg

C# Group number 24 Joni Saarinen Daniel Kullberg C# (pronounced C sharp) is a multi paradigm programming language developed by Microsoft. It is primarily an imperative language but support for functional

No Solution Equations Let s look at the following equation: 2 +3=2 +7

5.4 Solving Equations with Infinite or No Solutions So far we have looked at equations where there is exactly one solution. It is possible to have more than solution in other types of equations that are

Automata and Languages

Automata and Languages Computational Models: An idealized mathematical model of a computer. A computational model may be accurate in some ways but not in others. We shall be defining increasingly powerful

COMP 356 Programming Language Structures Notes for Chapter 4 of Concepts of Programming Languages Scanning and Parsing

COMP 356 Programming Language Structures Notes for Chapter 4 of Concepts of Programming Languages Scanning and Parsing The scanner (or lexical analyzer) of a compiler processes the source program, recognizing

Master of Sciences in Informatics Engineering Programming Paradigms 2005/2006. Final Examination. January 24 th, 2006

Master of Sciences in Informatics Engineering Programming Paradigms 2005/2006 Final Examination January 24 th, 2006 NAME: Please read all instructions carefully before start answering. The exam will be

Functional programming languages

Functional programming languages Part II: abstract machines Xavier Leroy INRIA Rocquencourt MPRI 2-4-2, 2007 X. Leroy (INRIA) Functional programming languages MPRI 2-4-2, 2007 1 / 73 Execution models for

Lecture Set 2: Starting Java

Lecture Set 2: Starting Java 1. Java Concepts 2. Java Programming Basics 3. User output 4. Variables and types 5. Expressions 6. User input 7. Uninitialized Variables CMSC 131 - Lecture Outlines - set

Formal Languages and Automata Theory - Regular Expressions and Finite Automata -

Formal Languages and Automata Theory - Regular Expressions and Finite Automata - Samarjit Chakraborty Computer Engineering and Networks Laboratory Swiss Federal Institute of Technology (ETH) Zürich March

Definitional Interpreters for Higher-Order Programming Languages *

Higher-Order and Symbolic Computation, 11, 363 397 1998) c 1998 Kluwer Academic Publishers, Boston. Manufactured in The Netherlands. Definitional Interpreters for Higher-Order Programming Languages * JOHN

GENERIC and GIMPLE: A New Tree Representation for Entire Functions

GENERIC and GIMPLE: A New Tree Representation for Entire Functions Jason Merrill Red Hat, Inc. jason@redhat.com 1 Abstract The tree SSA project requires a tree representation of functions for the optimizers

From Interpreter to Compiler and Virtual Machine

BRICS From Interpreter to Compiler and Virtual Machine Mads Sig Ager BRICS, University of Aarhus, Denmark Joint work with Dariusz Biernacki, Olivier Danvy, and Jan Midtgaard 1 Examples of machines Krivine

The Clean programming language. Group 25, Jingui Li, Daren Tuzi

The Clean programming language Group 25, Jingui Li, Daren Tuzi The Clean programming language Overview The Clean programming language first appeared in 1987 and is still being further developed. It was

Generalizing Overloading for C++2000 Bjarne Stroustrup AT&T Labs, Florham Park, NJ, USA Abstract This paper outlines the proposal for generalizing the overloading rules for Standard C++ that is expected

Lecture 18-19 Data Types and Types of a Language

Lecture 18-19 Data Types and Types of a Language April 29, 2014 Data Types and Types of a Language Data, Data Types and Types Type: Generalities Type Systems and Type Safety Type Equivalence, Coercion

C programming. Intro to syntax & basic operations

C programming Intro to syntax & basic operations Example 1: simple calculation with I/O Program, line by line Line 1: preprocessor directive; used to incorporate code from existing library not actually

Introduction. Compiler Design CSE 504. Overview. Programming problems are easier to solve in high-level languages

Introduction Compiler esign CSE 504 1 Overview 2 3 Phases of Translation ast modifled: Mon Jan 28 2013 at 17:19:57 EST Version: 1.5 23:45:54 2013/01/28 Compiled at 11:48 on 2015/01/28 Compiler esign Introduction

Lecture 9. Semantic Analysis Scoping and Symbol Table

Lecture 9. Semantic Analysis Scoping and Symbol Table Wei Le 2015.10 Outline Semantic analysis Scoping The Role of Symbol Table Implementing a Symbol Table Semantic Analysis Parser builds abstract syntax

BEGINNING ALGEBRA ACKNOWLEDMENTS

BEGINNING ALGEBRA The Nursing Department of Labouré College requested the Department of Academic Planning and Support Services to help with mathematics preparatory materials for its Bachelor of Science

Theory of Computation Lecture Notes

Theory of Computation Lecture Notes Abhijat Vichare August 2005 Contents 1 Introduction 2 What is Computation? 3 The λ Calculus 3.1 Conversions: 3.2 The calculus in use 3.3 Few Important Theorems 3.4 Worked

Intermediate-Code Generation

Intermediate-Code Generation Cosmin E. Oancea cosmin.oancea@diku.dk December 2012 Structure of a Compiler Programme text Lexical analysis Binary machine code Symbol sequence Assembly and linking Syntax

School of Informatics, University of Edinburgh

CS1Ah Lecture Note 5 Java Expressions Many Java statements can contain expressions, which are program phrases that tell how to compute a data value. Expressions can involve arithmetic calculation and method

CSCI 3136 Principles of Programming Languages

CSCI 3136 Principles of Programming Languages Faculty of Computer Science Dalhousie University Winter 2013 CSCI 3136 Principles of Programming Languages Faculty of Computer Science Dalhousie University

Fundamental Computer Science Concepts Sequence TCSU CSCI SEQ A

Fundamental Computer Science Concepts Sequence TCSU CSCI SEQ A A. Description Introduction to the discipline of computer science; covers the material traditionally found in courses that introduce problem

Satisfiability Checking

Satisfiability Checking First-Order Logic Prof. Dr. Erika Ábrahám RWTH Aachen University Informatik 2 LuFG Theory of Hybrid Systems WS 14/15 Satisfiability Checking Prof. Dr. Erika Ábrahám (RWTH Aachen

C# 3.0 Programming in the.net Framework (MS50150)

Duration: 6 days Course Description: This course provides students with the knowledge and skills to develop applications in the.net Framework 3.5 using the C# 3.0 programming language. The C# 3.0 revision

Curriculum Map. Discipline: Computer Science Course: C++

Curriculum Map Discipline: Computer Science Course: C++ August/September: How can computer programs make problem solving easier and more efficient? In what order does a computer execute the lines of code

CompuScholar, Inc. Alignment to Utah's Computer Programming II Standards

CompuScholar, Inc. Alignment to Utah's Computer Programming II Standards Course Title: TeenCoder: Java Programming Course ISBN: 978 0 9887070 2 3 Course Year: 2015 Note: Citation(s) listed may represent

Monads for functional programming Philip Wadler, University of Glasgow Department of Computing Science, University of Glasgow, G12 8QQ, Scotland (wadler@dcs.glasgow.ac.uk) Abstract. The use of monads to

Programming Languages

Programming Languages Qing Yi Course web site: www.cs.utsa.edu/~qingyi/cs3723 cs3723 1 A little about myself Qing Yi Ph.D. Rice University, USA. Assistant Professor, Department of Computer Science Office:

Timber: A Programming Language for Real-Time Embedded Systems

Timber: A Programming Language for Real-Time Embedded Systems Andrew P. Black, Magnus Carlsson, Mark P. Jones, Richard Kieburtz and Johan Nordlander Department of Computer Science and Engineering OGI School

Idris, a General Purpose Dependently Typed Programming Language: Design and Implementation

Under consideration for publication in J. Functional Programming 1 Idris, a General Purpose Dependently Typed Programming Language: Design and Implementation EDWIN BRADY School of Computer Science, University

Unboxed Polymorphic Objects for Functional Numerical Programming

Unboxed Polymorphic Objects for Functional Numerical Programming Christopher Rodrigues cirodrig@illinois.edu Wen-Mei Hwu w-hwu@illinois.edu IMPACT Technical Report IMPACT-12-02 University of Illinois at

Chapter 1. Logic and Proof

Chapter 1. Logic and Proof 1.1 Remark: A little over 100 years ago, it was found that some mathematical proofs contained paradoxes, and these paradoxes could be used to prove statements that were known

CS412/CS413. Introduction to Compilers Tim Teitelbaum. Lecture 18: Intermediate Code 29 Feb 08

CS412/CS413 Introduction to Compilers Tim Teitelbaum Lecture 18: Intermediate Code 29 Feb 08 CS 412/413 Spring 2008 Introduction to Compilers 1 Summary: Semantic Analysis Check errors not detected by lexical

Final Exam Review. CS 1428 Fall Jill Seaman. Final Exam

Final Exam Review CS 1428 Fall 2011 Jill Seaman 1 Final Exam Friday, December 9, 11:00am to 1:30pm Derr 241 (here) Closed book, closed notes, clean desk Comprehensive (covers entire course) 25% of your

COMPUTER SCIENCE TRIPOS

CST.98.5.1 COMPUTER SCIENCE TRIPOS Part IB Wednesday 3 June 1998 1.30 to 4.30 Paper 5 Answer five questions. No more than two questions from any one section are to be answered. Submit the answers in five

Detecting Pattern-Match Failures in Haskell. Neil Mitchell and Colin Runciman York University www.cs.york.ac.uk/~ndm/catch

Detecting Pattern-Match Failures in Haskell Neil Mitchell and Colin Runciman York University www.cs.york.ac.uk/~ndm/catch Does this code crash? risers [] = [] risers [x] = [[x]] risers (x:y:etc) = if x

On Understanding Types, Data Abstraction, and Polymorphism

1 Computing Surveys, Vol 17 n. 4, pp 471-522, December 1985 On Understanding Types, Data Abstraction, and Polymorphism Luca Cardelli AT&T Bell Laboratories, Murray Hill, NJ 07974 (current address: DEC

CSE 307: Principles of Programming Languages

Course Organization Introduction CSE 307: Principles of Programming Languages Spring 2015 R. Sekar Course Organization Introduction 1 / 34 Topics 1. Course Organization Info and Support Course Description