Functional Programming. Pure Functional Programming

Similar documents
Functional Programming. Pure Functional Programming

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

So what does studying PL buy me?

CSCI-GA Scripting Languages

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

A Second Look At ML. Chapter Seven Modern Programming Languages, 2nd ed. 1

CS 11 Ocaml track: lecture 2

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example

CSE 341 Section 5. Winter 2018

F# - LISTS. In this method, you just specify a semicolon-delimited sequence of values in square brackets. For example

CMSC 330, Fall 2013, Practice Problems 3

Programming Languages

Continuations and Continuation-Passing Style

OCaml. History, Variants. ML s holy trinity. Interacting with ML. Base type: Integers. Base type: Strings. *Notes from Sorin Lerner at UCSD*

Plan (next 4 weeks) 1. Fast forward. 2. Rewind. 3. Slow motion. Rapid introduction to what s in OCaml. Go over the pieces individually

Why OCaml? Introduction to Objective Caml. Features of OCaml. Applications written in OCaml. Stefan Wehr

Introduction to Objective Caml

Programming Languages

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

8. Functions (II) Control Structures: Arguments passed by value and by reference int x=5, y=3, z; z = addition ( x, y );

Programming Languages

CMSC 330, Fall 2013, Practice Problem 3 Solutions

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

Recap: Functions as first-class values

# true;; - : bool = true. # false;; - : bool = false 9/10/ // = {s (5, "hi", 3.2), c 4, a 1, b 5} 9/10/2017 4

CS Lectures 2-3. Introduction to OCaml. Polyvios Pratikakis

Functional Languages. CSE 307 Principles of Programming Languages Stony Brook University

Lab 10: OCaml sequences, comparators, stable sorting 12:00 PM, Nov 12, 2017

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

Booleans (aka Truth Values) Programming Languages and Compilers (CS 421) Booleans and Short-Circuit Evaluation. Tuples as Values.

Topic 5: Examples and higher-order functions

Any questions. Say hello to OCaml. Say hello to OCaml. Why readability matters. History, Variants. Plan (next 4 weeks)

CPL 2016, week 10. Clojure functional core. Oleg Batrashev. April 11, Institute of Computer Science, Tartu, Estonia

CS 321 Programming Languages

CS558 Programming Languages

CSc 372. Comparative Programming Languages. 4 : Haskell Basics. Department of Computer Science University of Arizona

Online Resource. Online introductory book on programming in SML (Standard ML): online.pdf

Hands-On Lab. Introduction to F# Lab version: Last updated: 12/10/2010. Page 1

Problem Solving, Programming, and Calculation

CSc 372 Comparative Programming Languages. 4 : Haskell Basics

Dialects of ML. CMSC 330: Organization of Programming Languages. Dialects of ML (cont.) Features of ML. Functional Languages. Features of ML (cont.

CHAPTER 4 FUNCTIONS. 4.1 Introduction

SML A F unctional Functional Language Language Lecture 19

Begin at the beginning

CS 415 Midterm Exam Spring SOLUTION

Organization of Programming Languages CS3200/5200N. Lecture 11

max function Next concat function max function What s the pattern? concat function More on recursion Higher-order functions

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

It is better to have 100 functions operate one one data structure, than 10 functions on 10 data structures. A. Perlis

Principles of Programming Languages COMP251: Functional Programming in Scheme (and LISP)

Lecture 5: Declarative Programming. The Declarative Kernel Language Machine. September 12th, 2011

Chapter 11 :: Functional Languages

Background. CMSC 330: Organization of Programming Languages. Useful Information on OCaml language. Dialects of ML. ML (Meta Language) Standard ML

CS558 Programming Languages

More Scheme CS 331. Quiz. 4. What is the length of the list (()()()())? Which element does (car (cdr (x y z))) extract from the list?

JVM ByteCode Interpreter

Forward recursion. CS 321 Programming Languages. Functions calls and the stack. Functions calls and the stack

Example Scheme Function: equal

INF 102 CONCEPTS OF PROG. LANGS FUNCTIONAL COMPOSITION. Instructors: James Jones Copyright Instructors.

News. Programming Languages. Complex types: Lists. Recap: ML s Holy Trinity. CSE 130: Spring 2012

CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion. Zach Tatlock Winter 2018

Anonymous Functions CMSC 330: Organization of Programming Languages

GE U111 Engineering Problem Solving & Computation Lecture 6 February 2, 2004

Factorial. Next. Factorial. How does it execute? Tail recursion. How does it execute? More on recursion. Higher-order functions

Chapter 15. Functional Programming Languages

Faculty of Engineering Computer Engineering Department Islamic University of Gaza C++ Programming Language Lab # 6 Functions

INF 212 ANALYSIS OF PROG. LANGS FUNCTION COMPOSITION. Instructors: Crista Lopes Copyright Instructors.

Function definitions. CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Example, extended. Some gotchas. Zach Tatlock Winter 2018

CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Zach Tatlock Winter 2018

Introduction to OCaml

Tail Recursion: Factorial. Begin at the beginning. How does it execute? Tail recursion. Tail recursive factorial. Tail recursive factorial

Chapter 15. Functional Programming Languages

Next. Tail Recursion: Factorial. How does it execute? Tail recursion. Tail recursive factorial. Tail recursive factorial.

List Functions, and Higher-Order Functions

egrapher Language Reference Manual

4/19/2018. Chapter 11 :: Functional Languages

Functional Programming for Imperative Programmers

CSE 413 Midterm, May 6, 2011 Sample Solution Page 1 of 8

Functional Programming. Introduction To Cool

News. Programming Languages. Recap. Recap: Environments. Functions. of functions: Closures. CSE 130 : Fall Lecture 5: Functions and Datatypes

Functional Programming and Haskell

Imperative programming in F#

Compiler Construction Lecture 05 A Simple Stack Machine. Lent Term, Lecturer: Timothy G. Griffin. Computer Laboratory University of Cambridge

CS422 - Programming Language Design

Patterns The Essence of Functional Programming

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Programming Languages and Techniques (CIS120)

COSE212: Programming Languages. Lecture 4 Recursive and Higher-Order Programming

CPS 506 Comparative Programming Languages. Programming Language Paradigm

Programming Languages and Compilers (CS 421)

Principles of Programming Languages

Programming Languages Fall 2013

Functional Programming

Today. Recap from last Week. Factorial. Factorial. How does it execute? How does it execute? More on recursion. Higher-order functions

9/21/17. Outline. Expression Evaluation and Control Flow. Arithmetic Expressions. Operators. Operators. Notation & Placement

CS 330 Lecture 18. Symbol table. C scope rules. Declarations. Chapter 5 Louden Outline

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

C Syntax Out: 15 September, 1995

Programming Languages

CS4215 Programming Language Implementation

Transcription:

Functional Programming With examples in F# Pure Functional Programming Functional programming involves evaluating expressions rather than executing commands. Computation is largely performed by applying functions to values. The value of an expression depends only on the values of its sub-expressions (if any). Evaluation does not produce side effects. The value of an expression cannot change over time. No notion of state. Computation may generate new values, but not change existing ones.

Simplicity Advantages No explicit manipulation of memory. Values are independent of underlying machine with assignments and storage allocation. Garbage collection. Power Recursion Functions as first class values Can be value of expression, passed as argument, placed in data structures. Need not be named. F# May be either interpreted or compiled. Interacting with the interpreter Supply an expression to be evaluated Bind a name to a value (could be a function) > 3.14159 val it : float = 3.14159 > let pi = 3.14159 val pi : float = 3.14159 > pi val it : float = 3.14159

Arithmetic Expressions > 5 * 7 val it : int = 35 > 5 * (6 + 4) val it : int = 50 > 5.0 + 3.2 val it : float = 8.2 > pi * 4.7 val it : float = 14.765473 Arithmetic Expressions (2) > 5.0 + 3 5.0 + 3 ------^ error: The type 'int' does not match the type 'float > 5.0 + float 3 val it : float = 8.0

Anonymous Functions The fun keyword creates anonymous functions. This can be useful when the function is used immediately or passed as a parameter to another function.!(fun param param -> expression) > let double = (fun x -> x + x) val double : int -> int > double 18 val it : int = 36 > (fun x -> x * 3) 18 val it : int = 54 Functions: Multiple Parameters Consider a function to add two numbers: > add 3 7 val it : int = 10 In F# we would define this as: > let add = (fun x -> (fun y -> x + y)) val add : int -> int -> int Notice that add is really a function that takes one parameter, x, and returns a second function that takes another parameter, y, and adds it to x. For example, the value of (add 3) is a function that takes one parameter and adds it to 3.

Functions: Multiple Parameters If we think of add as a function of two parameters, then (add 3) is a partial application of that function. Given the previous definition of add, we could define: > let add3 = (add 3) val add : int -> int -> int Now we can use add3: > add3 5 val it : int = 8 All of this makes sense because functions are true values. Function Definition Shorthand let name param param = expression! > let add x y = x + y val add : int -> int -> int > let add (x: float) y = x + y val add : float -> float -> float > add 3.2 1.8 val it : float = 5.0

If-Else Expressions Unlike if-else statements in imperative languages, if-else constructs are expressions, i.e. they have a value: if test then expression1 else expression2 If the test is true, the value is the value of expression1, otherwise the value of expression2. If-Else Example > let x = 5 > let y = 10 > let n = if (x > y) then x y else x + y val n : int = 15

Naming vs. Assignment In F# a let expression creates a new variable, it never changes the value of an existing variable. Similar to a declaration (as opposed to assignment) in C: int f(int i) { int x = 0; if (i > 10){ x = 1; } else { x = 2; } int f(int i) { int x = 0; if (i > 10){ int x = 1; } else { int x = 2; } } return x; } return x; Recursion Most non-trivial functions are recursive. Why is iteration not very useful in functional programming? To create a recursive function in F#, you must use the rec keyword. > let rec factorial n = if n = 0 then 1 else n * factorial (n-1) val factorial : int -> int > factorial 10 val it : int = 3628800

Tuples A tuple is defined as a comma separated collection of values. For example, (10, "hello") is a 2-tuple with the type (int * string). Tuples are useful for creating data structures or defining functions that return more than one value. > let swap (a, b) = (b, a) val swap : 'a * 'b -> 'b * 'a 'a and 'b denote generic types to be inferred from the function call: > swap ( day", night") val it : string * string = ( night", day") - Can also be used to bind multiple values in a let: > let x, y = (5, 7) val y : int = 7 val x : int = 5 Lists A list is a sequence of zero or more values of the same type. A list is written by enclosing its elements in [ ] separated by semicolons: > let firstlist = [ "a"; "b"; "c" ] val firstlist : string list = ["a"; "b"; "c"] F#, like all functional languages, implements its lists as linked lists. Essentially, a list node in F# consists of a value (its head) and a tail, which is another list.

Operations on Lists > firstlist val it : string list = ["one"; "two"; "three"] > List.length firstlist val it : int = 3 > List.head firstlist val it : string = "one" > List.tail firstlist val it : string list = ["two"; "three"] > firstlist @ ["four"; "five"] val it : string list = ["one"; "two"; "three"; "four"; "five"] > "zero"::firstlist val it : string list = ["zero"; "one"; "two"; "three"] List Operations (2) Most of the list operations would be easy to define ourselves. Example, length function: > let rec length list = if list = [] then 0 else length (List.tail list) + 1 val length : 'a list -> int when 'a : equality > length [2; 3; 5; 4; 1] val it : int = 5

Option Types An option type can hold two possible values: Some(x) or None. Option types are frequently used to represent optional values in calculations, or to indicate whether a particular computation has succeeded or failed. Example: Avoid divide by zero exception > let div x y = if y = 0.0 then None else Some (x/y) > div 4.0 3.2 val it : float option = Some 1.25 > div 4.2 0.0 val it : float option = None Pattern Matching > let rec length list = match list with [] -> 0 _ -> length (List.tail list) + 1 > let div x y = match y with 0.0 -> None _ -> Some (x/y) > let rec last list = match list with [] -> None [x] -> Some x _ -> last (List.tail list)

Efficiency: Cons vs. Append > let x1 = [] > let x2 = "c"::x1 > let x3 = "b"::x2 > let x4 = "a"::x3 > x1 val x1 : 'a list = [ ] > x2 val x2 : string list = ["c"] > x3 val x3 : string list = ["b"; "c"] > x4 val x4 : string list = ["a"; "b"; "c"] x4 x3 x2 x1 List Nodes a b c Efficiency: Cons vs. Append (2) List Nodes > let x1 = ["a"] > let x2 = x1 @ ["b"] x3 a > let x3 = x2 @ ["c"] > x1 val x1 : string list = ["a"] > x2 val x2 : string list = ["a"; "b"] > x3 val x3 : string list = ["a"; "b"; "c"]! x2 a b b c x1 a

Efficiency: Tail Recursion When a recursive function returns the result of its recursive call, there is no need to maintain a stack of activation records. > let rec last list = match list with [] -> None [x] -> Some x _ -> last (List.tail list) Efficiency: Tail Recursion (2) > let rec length list = match list with [] -> 0 _ -> length (List.tail list) + 1 > let rec length_help list acc = match list with [] -> acc _ -> length-help (List.tail list) (acc + 1) > let length list = length_help list 0

Nested Functions > F# allows programmers to nest functions inside other functions. This prevents the top level name space from becoming cluttered with helper functions: > let length list = let rec length_help list acc = match list with [] -> acc _ -> length_help (List.tail list) (acc + 1) length_help list 0 Applications: Insertion Sort let rec insertion_sort list = let rec insert n list = if List.length list = 0 then [n] else if n < (List.head list) then n::list else (List.head list)::(insert n (List.tail list)) if List.length list = 0 then list else insert (List.head list) (insertion_sort (List.tail list))

Applications: Merge Sort let rec merge_sort list = // merge two sorted lists (helper function) let rec merge x y = if x = [] then y else if y = [] then x else if (List.head x) < (List.head y) then (List.head x)::(merge (List.tail x) y) else (List.head y)::(merge x (List.tail y)) Applications: Merge Sort (2) // split a list in two (helper function) let rec split list (a, b) = if list = [] then (a, b) else split (List.tail list) (b, (List.head list)::a) // sort if (List.length list) < 2 then list else let fsthalf, sndhalf = split list ([], []) merge (merge_sort fsthalf) (merge_sort sndhalf)

Higher Order Functions: Map Higher order functions are functions that take functions are arguments or return functions. The List.map function takes a function and a list as arguments, and returns a list of values obtained by applying the function to each element of the list: > let double x = x + x > List.map double [ 2; 4; 6] val it : int list = [ 4; 8; 12 ] Example: Searching A directed acyclic graph in F# let g = [ ("a", ["b"; "c"; "d"]); ("b", []); ("c", ["e"]); ("d", ["f"; "g"]); ("e", []); ("f", ["h"; "i"; "j"]); ("g", []); ("h", []) ("i", []); ("j", []) ] A B C D E F G H I J

Searching (2) let rec successors node graph = if graph = [ ] then [ ] else let head = List.head graph if fst head = node then snd head else successors node (List.tail graph) let path_extensions path graph = List.map (fun node -> node::path) (successors (List.head path) graph) Searching (3) let rec expand graph goal paths = if paths = [ ] then [ ] else let first_path = List.head paths let remaining_paths = List.tail paths if List.head first_path = goal then first_path else expand graph goal ((path_extensions first_path graph) @ remaining_paths) let search graph start goal = List.rev (expand graph goal [ [ start ] ])

search g "a" "i" expand g "i" [["a"]]