Functional Programming with F# Overview and Basic Concepts

Similar documents
Python. chrysn

Interfaces Dynamic Filter Sorting Sorting SQL. Dynamic LINQ. Radu Nicolescu Department of Computer Science University of Auckland.

Lambda Calculus! Gunnar Gotshalks! LC-1

Typing λ-terms. Types. Typed λ-terms. Base Types. The Typing Relation. Advanced Formal Methods. Lecture 3: Simply Typed Lambda calculus

ITI Introduction to Computing II

2 Results I: Lifting Computer Science

Models of computation

Lambda-Calculus (I) 2nd Asian-Pacific Summer School on Formal Methods Tsinghua University, August 23, 2010

Review. Principles of Programming Languages. Equality. The Diamond Property. The Church-Rosser Theorem. Corollaries. CSE 230: Winter 2007

Constructors - Cont. must be distinguished by the number or type of their arguments.

Limitations of OCAML records

Information Flow Inference for ML

Introduction to Turing Machines

An Introduction to Z3

Modern Functional Programming and Actors With Scala and Akka

Lisp Introduction. Dr. Neil T. Dantam. Spring CSCI-498/598 RPM, Colorado School of Mines. Dantam (Mines CSCI, RPM) Lisp Spring / 88

ITI Introduction to Computing II

Reasoning About Imperative Programs. COS 441 Slides 10b

1 Introduction. 2 Recap The Typed λ-calculus λ. 3 Simple Data Structures

DiffSharp An AD Library for.net Languages

Introduction to lambda calculus Part 2

Beyond First-Order Logic

Programming Languages

Introduction to Z3. Bow-Yaw Wang. December 19, Institute of Information Science Academia Sinica, Taiwan

Programming Language Concepts, CS2104 Lecture 3

Computer Science Introductory Course MSc - Introduction to Java

MiniMat: Matrix Language in OCaml LLVM

GOTO the past / programs choose their own adventure. CSE 505: Programming Languages

Meta-programming & you

Introduction to Metalogic

CompA - Complex Analyzer

The LCF Approach to Theorem Proving

Quantum Functional Programming Language & Its Denotational Semantics

Supplementary Notes on Inductive Definitions

Google Go illustrated on the basis of Fibonacci numbers

Extending the Lambda Calculus: An Eager Functional Language

CS Lecture 19: Logic To Truth through Proof. Prof. Clarkson Fall Today s music: Theme from Sherlock

Embedded probabilistic programming

Hoare Logic: Reasoning About Imperative Programs

COMPUTER SCIENCE TRIPOS

Introduction to lambda calculus Part 6

6.001 Recitation 22: Streams

Harvard CS 121 and CSCI E-121 Lecture 14: Turing Machines and the Church Turing Thesis

From Operational Semantics to Abstract Machines

CPS506 Comparative Programming Languages All Questions. All questions as of November 23, 2017

Classical Program Logics: Hoare Logic, Weakest Liberal Preconditions

Models. Models of Computation, Turing Machines, and the Limits of Turing Computation. Effective Calculability. Motivation for Models of Computation

CS156: The Calculus of Computation

Halting and Equivalence of Program Schemes in Models of Arbitrary Theories

Lecture Notes on Data Abstraction

Rigorous Software Development CSCI-GA

Meta-Circularity, and Vice-Versa

Operational Semantics

Brief Introduction to Prolog

Logic. Propositional Logic: Syntax. Wffs

Adapted with permission from: Seif Haridi KTH Peter Van Roy UCL. C. Varela; Adapted w. permission from S. Haridi and P. Van Roy 1

Typed Arithmetic Expressions

Static Program Analysis

Undecidable Problems. Z. Sawa (TU Ostrava) Introd. to Theoretical Computer Science May 12, / 65

Knowledge base (KB) = set of sentences in a formal language Declarative approach to building an agent (or other system):

Lecture Notes on Inductive Definitions

Simply Typed Lambda-Calculi (II)

Algebraic Dynamic Programming

NICTA Advanced Course. Theorem Proving Principles, Techniques, Applications

Hoare Examples & Proof Theory. COS 441 Slides 11

Theory of Computer Science. Theory of Computer Science. D7.1 Introduction. D7.2 Turing Machines as Words. D7.3 Special Halting Problem

Lecture 7. Logic. Section1: Statement Logic.

Denotational semantics

Applied C Fri

Iris: Higher-Order Concurrent Separation Logic. Lecture 4: Basic Separation Logic: Proving Pointer Programs

Lecture Notes on Inductive Definitions

7 RC Simulates RA. Lemma: For every RA expression E(A 1... A k ) there exists a DRC formula F with F V (F ) = {A 1,..., A k } and

Basic Java OOP 10/12/2015. Department of Computer Science & Information Engineering. National Taiwan University

CSE 505, Fall 2005, Midterm Examination 8 November Please do not turn the page until everyone is ready.

Equalities and Uninterpreted Functions. Chapter 3. Decision Procedures. An Algorithmic Point of View. Revision 1.0

CSE 505, Fall 2009, Midterm Examination 5 November Please do not turn the page until everyone is ready.

Automated Reasoning Lecture 5: First-Order Logic

Simply Typed Lambda Calculus

CS156: The Calculus of Computation Zohar Manna Autumn 2008

Functions in Python L435/L555. Dept. of Linguistics, Indiana University Fall Functions in Python. Functions.

Artificial Intelligence Chapter 7: Logical Agents

Adapted with permission from: Seif Haridi KTH Peter Van Roy UCL. C. Varela; Adapted w. permission from S. Haridi and P. Van Roy 1

The Lambda Calculus. Stephen A. Edwards. Fall Columbia University

Programming Languages Fall 2013

Software Engineering using Formal Methods

Simple Type Extensions

Python & Numpy A tutorial

Simply Typed λ-calculus

Structure. Background. them to their higher order equivalents. functionals in Standard ML source code and converts

CS 4110 Programming Languages & Logics. Lecture 16 Programming in the λ-calculus

CS:4420 Artificial Intelligence

CSCE 551: Chin-Tser Huang. University of South Carolina

Applied Logic for Computer Scientists. Answers to Some Exercises

Theory of Computation

SEMANTICS OF PROGRAMMING LANGUAGES Course Notes MC 308

Softwaretechnik. Lecture 13: Design by Contract. Peter Thiemann University of Freiburg, Germany

Discrete Mathematics Review

Introduction to Logic and Axiomatic Set Theory

Notes from Yesterday s Discussion. Big Picture. CIS 500 Software Foundations Fall November 1. Some lessons.

Problem Decomposition: One Professor s Approach to Coding

Transcription:

Functional Programming with F# Overview and Basic Concepts Radu Nicolescu Department of Computer Science University of Auckland 27 Sep 2017 1 / 52

1 Background 2 Overview 3 Type System and Type Inference 4 Functions 5 Lambdas 6 printfn 7 Immutable Values and Mutable Variables 8 Pattern Matching 9 Collections 10 Recursion or Loops? 11 Exercise 12 Infinite virtual sequences 2 / 52

Brief historical overview 1.2 Alonzo Church s λ-expressions (1930s) John McCarthy s Lisp ( List processing ) : the 2nd oldest programming language (1958) Scheme (1975) Common Lisp (1984) Clojure (2007) Peter Landin s ISWIM ( If you See What I Mean ) : statically typed + type inference (1966) Haskell : purely functional (1990) Robin Milner s ML ( metalanguage ) : functional + side effects (1973) 4 / 52

Brief historical overview 2.2 Robin Milner s ML ( metalanguage ) : functional + side effects (1973) Standard ML (1990) CAML ( Categorical Abstract Machine Language ) (1985) OCAML (Objective CAML) : CAML + object layer (1996) Don Syme s F# : OCAML +.NET integration (2005) 5 / 52

F# FREE OPEN-SOURCE MULTI-PLATFORM F# : OCAML +.NET = functional programming + statically typed + type inference + side effects + objects +.NET + extensions (actors) 1 Functional programming ( Functional-first) 2 Object-oriented programming 3 Language-oriented programming (cf., DSL) Contrast with Anders Hejlsberg s C# 1 Object-oriented programming (Objects-first) 2 Elements of functional programming 6 / 52

How to use F# on Windows fsc : command-line compiler fsi : interactive VS F# project uses fsc also fsi: selection + Alt-Enter LINQPAD uses fsc 8 / 52

Resources F# Software Foundation http://fsharp.org/ Visual F# on MSDN https: //msdn.microsoft.com/en-us/library/dd233154.aspx F# for Fun and Profit http://fsharpforfunandprofit.com Try F# http:/www./tryfsharp.org F# Programming http://en.wikibooks.org/wiki/f_sharp_programming This handout s sequel is largely based on the Basic Concepts section of this wiki book 9 / 52

Resources Sources The Open Edition of the F# compiler, core library and tools https://github.com/fsharp/fsharp src/fsharp/fsharp.core https://github.com/fsharp/ fsharp/tree/master/src/fsharp/fsharp.core control.fs: async (async workflows), mailbox (agents/actors),... list.fs: List module seq.fs: Seq module prim-type.fs: operators, comparisons, lists (type), conversions,... 10 / 52

Basics Syntax (a bit controversial) Note light : based on indentation (cf., Python); offside rules! verbose types are rarely explicit : powerful type inference (but very strongly typed no automatic conversions) by default, variables are immutable values (cf., const) powerful pattern matching (kind of a more powerful switch case) Namespaces and modules, with functions statements classes (objects) 11 / 52

Starting Light syntax based on indentation - default 1 # l i g h t using System 1 open System y is an immutable value of F# type float (C# double!) 1 l e t y = 3. 0 F# printf is inspired from C 1 p r i n t f n y = %g y // y = 3 Can also use C# API 1 Console. W r i t e L i n e ( y = {0}, y ) // y = 3 12 / 52

Complete simple example F# 1 module Simple 2 open System 3 ( This can be a multi-line comment ) 4 // This is a single-line comment 5 6 l e t rec f i b n = 7 match n with 8 0 > 1 9 1 > 1 10 > f i b ( n 1) + f i b ( n 2) 11 12 [< EntryPoint >] 13 l e t main a r g s = 14 Console. W r i t e L i n e ( f i b 5 : {0}, ( f i b 5 ) ) 15 0 these are static functions (cp. instance/virtual) 13 / 52

Same simple example translated into C# 1 using System ; 2 p u b l i c s t a t i c c l a s s Simple { 3 p u b l i c s t a t i c i n t f i b ( i n t n ) { 4 switch ( n ) { 5 case 0 : return 1 ; 6 case 1 : return 1 ; 7 d e f a u l t : 8 return Simple. f i b ( n 1) + Simple. f i b ( n 2 ) ; 9 } 10 } 11 p u b l i c s t a t i c void main ( s t r i n g [ ] arg ) { 12 Console. W r i t e L i n e ( f i b 5 : {0}, Simple. f i b ( 5 ) ) ; 13 } 14 p u b l i c s t a t i c void Main ( s t r i n g [ ] a r g s ) { 15 Simple. main ( a r g s ) ; 16 } 17 } 14 / 52

Data Types primitives: int, single float=double, string,... extensions: bigint=biginteger, complex,... functions, of course, as first-class citizens; all are curried (i.e., functions of one parameter only)! collections: seq< T> (= IEnumerable<T>), array< T>, list< T> (immutable, and List <T>) tuples and records ( struct) discriminated unions (implemented as a.net base class with tags + derived classes) other types: classes, interfaces 16 / 52

Bind values and print them 1 l e t x1 : i n t = 3 + 4 // explicitly declared as int 2 3 l e t x2 = 3 + 4 // inferred as int, from right-hand-side 4 5 p r i n t f n r e s u l t s = %d %d x1 x2 x1 and x2 are immutable values, improperly called variables 3 and 4 are int literals %d is an int format specification 17 / 52

Simple unary functions on primitive types 1 l e t i n c ( x : i n t ) : i n t = x + 1 // explicitly declared 2 3 // v a l i n c : i n t > i n t : Func<int, int > 4 5 p r i n t f n i n c 3 = %d ( i n c 3) 6 7 l e t i n c i x = x + 1 // inferred types 8 9 // v a l i n c i : i n t > i n t 10 11 p r i n t f n i n c i 3 = %d ( i n c i 3) 1 is int x is int + is int addition x+1 is int (no automatic conversion) parentheses (inc 3) are required, otherwise we would have two arguments to print 19 / 52

Curried function of two parameters 1 l e t a d d i x y = x + y 2 3 // v a l a d d i : i n t > i n t > i n t // i n t > ( int >i n t ) 4 // Func<int, Func<int, int >> 5 6 p r i n t f n a d d i 3 4 = %d ( a d d i 3 4) addi seems to be be a function taking two int parameters In reality, addi is a high-order function (aka functional), taking one int parameter and returning another function taking one more int parameter The > arrow is right associative: int > (int > int) The invocation (addi 3 4) can also be written as ((addi 3) 4) Although overloaded, arithmetic operations (such as +) are defaulted as int operations, unless explicitly required otherwise 20 / 52

Partial evaluation 1 l e t addi3 = a d d i 3 2 3 // v a l addi3 : i n t > i n t 4 5 p r i n t f n addi3 4 = %d ( a ddi3 4) 6 7 p r i n t f n addi3 7 = %d ( a ddi3 7) The expression (addi 3) is the partial evaluation of addi after fixing its first parameter a to 3 The returned addi3 is a classical low-level function, expecting one more int parameter 21 / 52

Curried function of two parameters - op version 1 l e t (++) x y = x + y 2 // (++): i n t > i n t > i n t // i n t > ( int >i n t ) 3 4 l e t a = (++) 3 4 5 l e t c = 3 ++ 4 6 p r i n t f n a=%d, c=%d a c 7 8 l e t b = ((++) 3) 4 9 10 l e t ``+3`` = (++) 3 11 // (+3): i n t > i n t 12 13 l e t d = ``+3`` 4 14 p r i n t f n b=%d, d=%d b d 22 / 52

Pointers to functions 1 type F I I I = i n t > i n t > i n t 2 // Func<int, Func<int, int >> 3 4 l e t f : F I I I = a d d i // explicit type 5 l e t f = a d d i // inferred type 6 7 p r i n t f n f 3 4 = %d ( f 3 4) 8 9 l e t addf ( x : f l o a t ) ( y : f l o a t ) = x + y 10 // l e t g : F I I I = addf compilation error FIII is an alias for the type of all functions with the signature int > (int > int) f is compatible and can be bound to addi, but not to addf For interacting with.net, use the special construct delegate 23 / 52

Lambdas 1 l e t f x = x + 1 // F# 2 3 l e t g = fun x > x + 1 // F# lambda 4 5 Func<int, int > h = x => x + 1 // C# lambda Lambdas are introduced by the keyword fun 25 / 52

(printfn... ) defines a function! 1 p r i n t f n two i n t e g e r s = %d %d 4 7 2 3 ( p r i n t f n two i n t e g e r s = %d %d ) 4 7 4 5 ( ( p r i n t f n two i n t e g e r s = %d %d ) 4) 7 6 7 // p r i n t f n two i n t e g e r s = %d %d 4. 0 7. 0 8 // compilation error The signature of (printfn format) is determined by the % format specifications which appear inside the format The compiler checks if the given % format specifications are format compatible E.g., %d is compatible will all integer types, %A with almost all objects 27 / 52

(printfn... ) defines a function! 1 l e t pr = p r i n t f n two i n t e g e r s = %d %d 2 3 // v a l pr : ( i n t > i n t > unit ) 4 5 pr 4 7 pr is a high-order functional which in the end prints two int numbers given one after the other roughly, type unit corresponds to void; in F#, it also has a single value, () 28 / 52

Mutable variables 1 l e t mutable c = 1 2 3 p r i n t f n %d c // 1 4 5 c < c + 1 6 7 p r i n t f n %d c // 2 c is explicitly declared mutable it can be modified by the < operator (not by =) mutable variables are not really accepted in closures i.e. mutables in closures are automatically transformed in ref references, which do work with closures 30 / 52

Propositional calculus Syntax 1 type Prop = // instances 2 F a l s e // F a l s e f a l s e 3 True // True true 4 Not of Prop // Not ( p ) p 5 And of Prop Prop // And ( p, q ) p q 6 Or of Prop Prop // Or ( p, q ) p q This defines a discriminated union family, which will be discussed in more detail later Syntactically, Prop instances correspond to formulas of a simple propositional calculus with two logical values (True and False) Logical operators appear as prefix functions 32 / 52

Propositional calculus Samples 1 l e t s h o u l d B e F a l s e = And ( F a l s e, Not F a l s e ) 2 3 l e t shouldbetrue = Or ( True, Not True ) 4 5 l e t complexlogic = 6 And ( And ( True, Or ( Not ( True ), True ) ), 7 Or ( And ( True, Not ( True ) ), Not ( True ) ) ) What are their logical values? 33 / 52

Propositional calculus Semantics 1 l e t rec e v a l x = 2 match x with 3 F a l s e > f a l s e 4 True > true 5 Not ( prop ) > not ( e v a l prop ) 6 And ( prop1, prop2 ) > ( e v a l prop1 )&&( e v a l prop2 ) 7 Or ( prop1, prop2 ) > ( e v a l prop1 ) ( e v a l prop2 ) eval defines the correct semantics rec indicates a recursive function (required) here, match corresponds to a switch/case statement 34 / 52

Propositional calculus Sample evaluations 1 p r i n t f n s h o u l d B e F a l s e : %b ( e v a l s h o u l d B e F a l s e ) 2 // f a l s e 3 4 p r i n t f n shouldbetrue : %b ( e v a l shouldbetrue ) 5 // true 6 7 p r i n t f n complexlogic : %b ( e v a l complexlogic ) 8 // f a l s e %b is the format specification for bool values 35 / 52

Collections Bird s eye view 1 l e t m y l i s t = [ 1 0 ; 2 0 ; 30 ] 2 3 l e t myarray = [ 1 0 ; 2 0 ; 30 ] 4 l e t v = myarray. [ 2 ] // 30 5 6 l e t myseq = seq { f o r i i n 1.. 3 do y i e l d i 10 } native F# lists are simple linked lists F# arrays are C#.NET arrays F# seqs are C#.NET sequences, i.e. IEnumerable<> (e.g. virtual) discriminated unions, tuples, records, structs, classes,... 37 / 52

Processing collections by high-level functionals Specialised modules: native F# lists : List module : map, collect, filter, length,... F# arrays : Array module : map, collect, filter, length,... F# seqs : Seq module : map, collect, filter, length,... IEnumerable<>: LINQ : Select, SelectMany, Where, Count,... Why specialised modules? List module : functions take and return native lists - eager Array module : functions take and return arrays - eager Seq module : functions take and return sequences - deferred/lazy, as much as possible (cf. LINQ) 38 / 52

Bird s eye view on lists 1 l e t c o l l e c t i o n = [ 1 0 ; 2 0 ; 30 ] // 10 : : [ 2 0 ; 3 0 ] 2 // 10 : : 20 : : [ 3 0 ] 3 // 10 : : 20 : : 30 : : [ ] Sidebar on lists: singly linked lists, head access is O(1), element access is O(n). 1 type l i s t < T> = // also T l i s t 2 ( [ ] ) 3 ( : : ) of T l i s t < T> T list inherited from OCAML; list < T> inherited from.net For more details, please see the List module: http://msdn.microsoft.com/en-us/library/dd233224.aspx 39 / 52

Collections: list intro our collection is an F# specific immutable literal list ( new LinkedList<int> { 10, 20, 30 }) is a non-empty list which has a head item, 10, and a tail list, [20; 30] could have also been constructed by pre-pending the head 10 to the list [20; 30]: 10 :: [20; 30], and so on... the empty list is indicated by [ ] operator :: can be used in two ways: 1 to construct lists (on the right-hand side ) and 2 to de-construct lists, in pattern matching (on the left-hand side, more later) 40 / 52

Processing collections 1 l e t x = [ 1 0 ; 2 0 ; 3 0 ] 2 3 // explicit loops 4 f o r v i n x do p r i n t f n %d v 5 6 // high-level functionals 7 x > L i s t. i t e r ( fun v > p r i n t f n %d v ) 8 9 L i s t. i t e r ( fun v > p r i n t f n %d v ) x 42 / 52

Recursive processing with pattern matching 1 // l e t rec p r i n t ( x : i n t l i s t ) = // l i s t <int > 2 3 l e t rec p r i n t x = 4 match x with 5 [ ] > ( ) 6 v : : t a i l > 7 p r i n t f n %d v 8 p r i n t t a i l 9 10 p r i n t x here, :: is used for pattern matching and indicates an automatic decomposition of list items into a head and a tail 43 / 52

Various ways to map a collection 1 l e t c = [ 1 0 0 ; 200; 300] 2 3 l e t c2 = c > L i s t. map ( fun x > x+x ) 4 5 l e t c2 = c > Seq. map ( fun x > x+x ) 6 7 l e t c2 = c. S e l e c t ( fun x > x+x ) 8 9 l e t c2 = query { f o r x i n c do s e l e c t ( x+x ) } 10 11 p r i n t f n %A, %A, %A, %A c2 c2 c2 c2 Seq module Enumerable, seq< T> = IEnumerable<T> F# s query expressions are similar to C# s query expressions (comprehensions); more later 44 / 52

Exercise essentially, a catamorphism Compute the sum of squares of a given float list, using: Imperative programming explicit loops and mutable variables FP with recursive functions FP with one F# fold or one LINQ Aggregate FP with a query expression Sample input: 1 l e t data = [ 1 0. ; 2 0. ; 3 0. ; 4 0. ] Sample output: 1 sum = 3000. 46 / 52

Exercise Imperative programming 1 l e t data = [ 1. ; 2. ; 3. ; 4. ] 2 // 1ˆ2 + 2ˆ2 + 3ˆ2 + 4ˆ2 = 30 3 4 l e t sumsquares1 ( data : f l o a t l i s t ) : f l o a t = 5 l e t mutable a = 0. 6 f o r x i n data do 7 a < a + x x 8 a // r e t u r n 9 10 p r i n t f n %.0 f ( sumsquares1 data ) 47 / 52

Exercise recursive functions 1 l e t data = [ 1. ; 2. ; 3. ; 4. ] 2 // 1ˆ2 + 2ˆ2 + 3ˆ2 + 4ˆ2 = 30 3 4 l e t rec sumsquares2 ( data : f l o a t l i s t ) : f l o a t = 5 match data with 6 [ ] > 0. 7 h : : t > 8 ( sumsquares2 t ) + h h 9 10 p r i n t f n %.0 f ( sumsquares2 data ) Challenge: make this tail-recursive! 48 / 52

Exercise List.fold or LINQ Aggregate 1 l e t data = [ 1. ; 2. ; 3. ; 4. ] 2 // 1ˆ2 + 2ˆ2 + 3ˆ2 + 4ˆ2 = 30 3 4 l e t sumsquares3 ( data : f l o a t l i s t ) : f l o a t = 5 data > L i s t. f o l d ( fun a x > a + x x ) 0. 6 7 p r i n t f n %.0 f ( sumsquares3 data ) 8 9 l e t sumsquares4 ( data : f l o a t l i s t ) : f l o a t = 10 data. Aggregate ( 0., fun a x > a + x x ) 11 12 p r i n t f n %.0 f ( sumsquares4 data ) 49 / 52

Exercise LINQ-like query expression 1 l e t data = [ 1. ; 2. ; 3. ; 4. ] 2 // 1ˆ2 + 2ˆ2 + 3ˆ2 + 4ˆ2 = 30 3 4 l e t sumsquares5 ( data : f l o a t l i s t ) : f l o a t = 5 query { f o r x i n data do sumby ( x x )} 6 7 p r i n t f n %.0 f ( sumsquares5 data ) 50 / 52

Infinite virtual sequences 1 l e t pow2 = seq { 2 l e t mutable n, n2 = 0, 1 3 while true do 4 y i e l d n2 5 n2 < n2 2 6 n < n + 1 7 } 1 pow2 > Seq. take 20 2 > Seq. i t e r i ( fun i k >... ) 52 / 52