Lecture 23 Functional Programming Languages and the Influence of Lambda Calculus COMS W4115 Programming Languages & Translators Maria Ayako Taku mat2185@columbia.edu COMS W4115 - PLT Columbia University 1 April 24, 2013 Why Functional Programming? You may have heard that: Simple XOR program: (1) functional programs are let xor p = match p with (false, x) -> x | (true, x) -> not x;; very succinct and elegant, but… (2) they take forever to write and understand COMS W4115 - PLT Columbia University 2 April 24, 2013 Outline I. What is Functional Programming? II. Lambda Calculus' Influence on Functional Programming III. Benefits of Functional Programming IV. OCaml in Action: An Entire Interpreter in 3 slides COMS W4115 - PLT Columbia University 3 April 24, 2013 What is Functional Programming? • A "programming paradigm" that focuses on the evaluation of functions • Programs are defined as recursive functions, where each takes a single input and outputs a single result. • Recall lambda calculus nests functions in this manner. Ex: (+ (* 1 2) (- 4 3)) In OCaml: let f = let a = 1*2 in let b = 4-3 in a + b;; COMS W4115 - PLT Columbia University 4 April 24, 2013 What is Functional Programming? • One important trademark of Functional Programming: It avoids both changes in state and mutable data These expressions are not equal. //F# let a=42; //C# int a=42; Conceptually, they are more like this. //F# let a=42; //C# static int a(){ return 42; } http://johnnycoder.com/blog/2009/04/20/functional-programming-part-1/ COMS W4115 - PLT Columbia University 5 April 24, 2013 What is Functional Programming? Some Common (more or less) FP Languages: So what's the value in functional programming? • • • • • Are its benefits worth taking the time to learn it and overcoming the (possibly) steep learning curve? LISP OCaml Haskell Erlang F# (multi-paradigm) COMS W4115 - PLT Columbia University 6 April 24, 2013 Outline I. What is Functional Programming? II. Lambda Calculus' Influence on Functional Programming III. Benefits of Functional Programming IV. OCaml in Action: An Entire Interpreter in 3 slides COMS W4115 - PLT Columbia University 7 April 24, 2013 Lambda Calculus' Influence • The syntax and theory of Functional Programming is highly influenced by lambda calculus. • Knowledge of lambda calculus means that FP is easier to learn, understand, and use efficiently. You might recognize some of the following FP syntax traits from lambda calculus… COMS W4115 - PLT Columbia University 8 April 24, 2013 Lambda Calculus' Influence Function Abstraction Lambda Calculus Recap A function abstraction consists of four parts: 1. 2. 3. 4. λx.expr a lambda followed by a single variable, a period, and then an expression COMS W4115 - PLT Columbia University 9 April 24, 2013 Lambda Calculus' Influence Function Abstraction Lambda Calculus: OCaml: λx.expr fun x -> expr;; Algebra: f(x) = expr COMS W4115 - PLT Columbia University 10 April 24, 2013 Lambda Calculus' Influence Function Abstraction The Let Command • Named Functions: OCaml strays from pure functional programming at times. fun x -> expr;; is equivalent to let myFunc x = expr;; • The "let" command can be used to allow one to create named functions COMS W4115 - PLT Columbia University 11 April 24, 2013 Lambda Calculus' Influence Function Abstraction An OCaml "let" example Similar code in Java COMS W4115 - PLT Columbia University # let fToc temp = (temp -. 32.0)/. 1.8;; # fToc 98.6;; - : float = 36.99999999 double fToc (double temp) { return (temp-32)/1.8; } fToc(98.6); 12 April 24, 2013 Lambda Calculus' Influence Beta Reductions Lambda Calculus Recap A function application is evaluated via a beta reduction Examples: (λx.xzx)y → [y/x]xzx = yzy (λx.+ 1 x)7 → + 1 7 = 8 Which occurs when an actual value is substituted for a variable Layman's Terms: (λx.expr1)expr2 means "replace every instance of x in expr1 with expr2" COMS W4115 - PLT Columbia University 13 April 24, 2013 Lambda Calculus' Influence Beta Reductions OCaml: Lambda Calculus: (fun x ->expr1)expr2;; (λx.expr1)expr2 Example Usage: (fun x ->x*x)5;; (* Evaluates to 5*5 = 25 *) COMS W4115 - PLT Columbia University 14 April 24, 2013 Lambda Calculus' Influence Beta Reductions The Let Command (fun x ->expr1)expr2;; The "let" command can once again be used to perform similar functionality to the "fun" command. COMS W4115 - PLT Columbia University Is semantically equivalent to: let x = expr2 in expr1;; Example Usage: let x = 5 in x*x;; (* Evaluates to 5*5=25*) 15 April 24, 2013 Outline I. What is Functional Programming? II. Lambda Calculus' Influence on Functional Programming III. Benefits of Functional Programming IV. OCaml in Action: An Entire Interpreter in 3 slides COMS W4115 - PLT Columbia University 16 April 24, 2013 Benefits of Functional Programming A few benefits in a nutshell: 1. Succinct Code 2. Encourages disciplined and logical thinking 3. Lazy Evaluation 4. Higher Level Functions Example: List.fold_left (fun s e ->s + e) 0 [42; 17; 120];; 5. No Side Effects & Referential Transparency COMS W4115 - PLT Columbia University 17 April 24, 2013 Benefits of Functional Programming No Side Effects Side Effect: a function or expression has a side effect if it modifies state or has an observable interaction with the "outside world." Examples: • Modify global/static variables • Modify arguments • Write data to a display or file Functional programs contain no assignment statements. So variables, once given a value, never change. COMS W4115 - PLT Columbia University 18 April 24, 2013 Benefits of Functional Programming No Side Effects Simple Side Effect Example in Java static int x = 5; static void changeX (int a){ x = a; } changeX(4); // This function has the side effect // of changing the value of global var x COMS W4115 - PLT Columbia University 19 April 24, 2013 Benefits of Functional Programming Referential Transparency Referential Transparency: An expression (e.g., function) is referentially transparent if it always produces the same output for the same input. Lack of side effects results in referential transparency. COMS W4115 - PLT Columbia University Because of this behavior, a variable/expression can always be replaced with its value without changing the behavior of a program if that language has Referential Transparency. 20 April 24, 2013 Benefits of Functional Programming Referential Transparency Lack of Referential Transparency in Java static int x = 10; static int add(int a){ return a + x; } add(1); // returns 11 x = 0; add(1); // returns 10, even though same input. NOT RT! COMS W4115 - PLT Columbia University 21 April 24, 2013 Why are Referential Transparency and Lack of Side Effects Good? • Elimination of bugs • Debugging in general is easier • Independence of evaluation order • Safe reuse of subprograms • Safe multithreading COMS W4115 - PLT Columbia University 22 April 24, 2013 Why are Referential Transparency and Lack of Side Effects Good? Easier and Better Compiling Easier to Compile – It's not only people that benefit from being able to better predict and understand a program's behavior Better Compiling – optimization via: – Memoization – Parallelization – Common Subexpression Elimination COMS W4115 - PLT Columbia University 23 April 24, 2013 Outline I. What is Functional Programming? II. Lambda Calculus' Influence on Functional Programming III. Benefits of Functional Programming IV. OCaml in Action: An Entire Interpreter in 3 slides COMS W4115 - PLT Columbia University 24 April 24, 2013 Implementing an Interpreter in OCaml • We will build a simple desk calculator to perform integer arithmetic. • You recall the basic block diagram of a simple interpreter: Lexer tokens Parser Input (arithmetic expression) COMS W4115 - PLT Columbia University AST AST Walker Output (evaluated arithmetic expression) 25 April 24, 2013 Implementing an Interpreter in OCaml scanner.mll ast.mli { open Parser } rule token = parse [’ ’ ’\t’ ’\r’ ’\n’] | ’+’ | ’-’ | ’*’ | ’/’ | [’0’-’9’]+ as lit | eof { token lexbuf } { PLUS } { MINUS } { TIMES } { DIVIDE } { LITERAL (int_of_string lit) } { EOF } type operator = Add | Sub | Mul | Div type expr = Binop of expr * operator * expr | Lit of int Courtesy of Stephen Edwards' PLT Lecture Slides: http://www.cs.columbia.edu/~sedwards/classes/2012/w4115-fall/ocaml.pdf COMS W4115 - PLT Columbia University 26 April 24, 2013 Implementing an Interpreter in OCaml parser.mly %{ open Ast %} %token PLUS MINUS TIMES DIVIDE EOF %token <int> LITERAL %left PLUS MINUS %left TIMES DIVIDE expr: expr PLUS expr | expr MINUS expr | expr TIMES expr | expr DIVIDE expr | LITERAL { Binop($1, Add, $3) } { Binop($1, Sub, $3) } { Binop($1, Mul, $3) } { Binop($1, Div, $3) } { Lit($1) } %start expr %type <Ast.expr> expr %% COMS W4115 - PLT Columbia University 27 April 24, 2013 Implementing an Interpreter in OCaml AST Walker: calc.ml open Ast let rec eval = function Lit(x) -> x | Binop (e1, op, e2) -> let v1 = eval e1 and v2 = eval e2 in match op with Add -> v1 + v2 | Sub -> v1 - v2 | Mul ->v1 * v2 | Div -> v1 / v2 let _ = let lexbuf = Lexing.from_channel stdin in let expr = Parser.expr Scanner.token lexbuf in let result = eval expr in print_endline (string_of_int result) COMS W4115 - PLT Columbia University 28 April 24, 2013 Quick Side Note: Pattern Matching in OCaml Pattern Matching a Parameter (function…) Pattern Matching a Value (match…with) function param1 -> expr1 | param2 -> expr2 | param3 -> expr3 match expr with param1 -> expr1 | param2 -> expr2 | param3 -> expr3 Main difference is how the pattern matcher receives its value to match COMS W4115 - PLT Columbia University 29 April 24, 2013 Quick Side Note: Pattern Matching in OCaml If you recall the XOR program from the beginning of this lecture, you should now be able to understand how this works. Hint: Variables, such as "x" will match anything and are bound to a value when the pattern matches. let xor p = match p with (false, x) -> x | (true, x) -> not x;; COMS W4115 - PLT Columbia University 30 April 24, 2013 Compiling the Interpreter $ ocamllex scanner.mll # create scanner.ml 8 states, 267 transitions, table size 1116 bytes $ ocamlyacc parser.mly # create parser.ml and parser.mli $ ocamlc –c ast.mli # compile AST types $ ocamlc –c parser.mli # compile parser types $ ocamlc –c scanner.ml # compile the scanner $ ocamlc –c parser.ml # compile the parser $ ocamlc –c calc.ml # compile the interpreter $ ocamlc –o calc parser.cmo scanner.cmo calc.cmo $ ./calc 2*3+4*5 26 $ COMS W4115 - PLT Columbia University 31 April 24, 2013 So Why Functional Programming? It's hard to get to compile, but once it compiles, it works -Unknown PLT Student COMS W4115 - PLT Columbia University 32 April 24, 2013 References • Edwards, Stephen. “An Introduction to Objective Caml.” http://www.cs.columbia.edu/~sedwards/classes/2012/w 4115-fall/ocaml.pdf • Huges, John. “Why Functional Programming Matters.” Research Topics in Functional Programming, AddisonWesley, 1990: pp 17-42 • “Advantages of Functional Programming.” http://c2.com/cgi/wiki?AdvantagesOfFunctionalProgram ming COMS W4115 - PLT Columbia University 33 April 24, 2013