cis192: python programming - functional...

24
CIS192: Python Programming Functional Programming Harry Smith University of Pennsylvania February 1, 2017 Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 1 / 24

Upload: others

Post on 04-Aug-2020

21 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

CIS192: Python ProgrammingFunctional Programming

Harry Smith

University of Pennsylvania

February 1, 2017

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 1 / 24

Page 2: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Outline

1 Function ArgumentsPositional and Named ArgumentsVariable Number of ArgumentsVariables Declared Outside Function

2 Functional ProgrammingBackgroundHigher Order FunctionsPartial Application

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 2 / 24

Page 3: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Positional Arguments

def func(arg1, arg2, arg3):I arg1 arg2 and arg3 are positional argumentsI When calling func exactly 3 arguments must be givenI The order in the call determines which arg they are bound to

func(a, b, c)I The expressions a, b, c are evaluated before the callI The value of a is bound to arg1 in the body of funcI Likewise b to arg2 and c to arg3I Calling a function with the wrong number of args gives aTypeError

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 3 / 24

Page 4: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Named Arguments

After the positional args, named args are alloweddef func(arg1, named1=val1, named2=val2):

I named1 and named2 are variables usable in the body of funcI val1 and val2 are default values for those variables.I Omitting named arguments in a call uses the default value

func(a, named2=b, named1=c)I named arguments can be given out of order

func(a, named2=b)I The default value, val1 will be bound to named1

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 4 / 24

Page 5: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Default Arguments

Default arguments are evaluated when the function is definedIn all calls, the object that the expression evaluated to will be used.If the default is mutable, updates in one call effect following callsdef func(a=[]) Will mutate the default on each call

def func(a=None):if a is None:a = []

Use None as the default to avoid mutation

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 5 / 24

Page 6: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Memoization

Memoization is an optimization technique that stores results offunction callsThe previously computed answers can be looked up on later callsUse a dictionary default arg to store answersdef func(arg, cache={}):

Store answers in cache[arg] = ans

Check for arg in cache before doing any work

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 6 / 24

Page 7: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Outline

1 Function ArgumentsPositional and Named ArgumentsVariable Number of ArgumentsVariables Declared Outside Function

2 Functional ProgrammingBackgroundHigher Order FunctionsPartial Application

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 7 / 24

Page 8: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

*args

A variable number of positional arguments can be specifedUse *args in between positional and named args

I Could use any identifier but args is conventionaldef func(arg1, *args, named=val)

I args is a tuple of 0 or more objectsfunc(a, b, c)

I arg1 = a, args = (b, c)I named gets the default object

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 8 / 24

Page 9: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Required Keyword Args

Any args after *args are keyword argsIf there is no default value specified, they areRequired Keyword Argsdef func(*args, named):

I named is a required keword arg

To specify required keyword args without allowing variablepositional args use *def func(arg1, *, named)

I named is a required kwargI func must take exactly one pos arg and one kwarg

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 9 / 24

Page 10: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

**kwargs

A variable number of kwargs can be specifedUse **kwargs at the end

I Could use any identifier but kwargs is conventionaldef func(arg1, *args, named=val, **kwargs)

I kwargs is a dictionary of strings to valuesI The keys of kwargs are the names of the keyword args

func(a, extra1=b, extra2=c)I arg1 = a, args = tuple()I named gets the default objectI kwargs = {’extra1’: b, ’extra2’: c}

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 10 / 24

Page 11: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

*/** in Function Definition

def(*args) args is a tuple that can take 0 or more valuesdef(**kwargs) kwargs is a dictionary that can take 0 or morekey-value pairs

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 11 / 24

Page 12: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

*/** in Function Calls

func(*expr)I expr is an iterableI It gets unpacked as the positional arguments of funcI Equivalentlyseq = list(expr); func(seq[0], seq[1], ...)

func(**expr)I expr is a dictionary of form {’string’: val, ...}I It gets unpacked as the keyword arguments of funcI Equivalently func(string=val, ...)

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 12 / 24

Page 13: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Outline

1 Function ArgumentsPositional and Named ArgumentsVariable Number of ArgumentsVariables Declared Outside Function

2 Functional ProgrammingBackgroundHigher Order FunctionsPartial Application

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 13 / 24

Page 14: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Closures

A function that knows about variable defined outside the function

a = 42def func():print(a)

func is a closure because it knows about aClosures are read-only in Python

a = 42def func():print(a)a += 1

UnboundLocalError: local variable ’a’ referenced beforeassignment

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 14 / 24

Page 15: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

global

global can circumvent read-only closuresthe global keyword declares certain variables in the currentcode block to reference the global scope

a = 42def func():global aprint(a)a += 1

This does not raise an errorVariables following global do not need to be bound already

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 15 / 24

Page 16: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Outline

1 Function ArgumentsPositional and Named ArgumentsVariable Number of ArgumentsVariables Declared Outside Function

2 Functional ProgrammingBackgroundHigher Order FunctionsPartial Application

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 16 / 24

Page 17: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Background

Functional programming started with lambda(λ) calculusI Alternative to Turing machines for exploring computabilityI Expresses programs as functions operating on other functions

Functional programming attempts to make it easier to reasonabout program behavior

I Mathematical interpretation of functions allows mathematical proofs

If data is immutable and there are no side-effects then functionsalways behave the same wayPython data is mutable and allows side-effects

I Has some functional conceptsI Not an ideal functional programming environment

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 17 / 24

Page 18: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Outline

1 Function ArgumentsPositional and Named ArgumentsVariable Number of ArgumentsVariables Declared Outside Function

2 Functional ProgrammingBackgroundHigher Order FunctionsPartial Application

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 18 / 24

Page 19: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

First Class Functions

A higher order function is a function that:I Takes a function as one of its inputsI Outputs a function

You can use functions anywhere you would use a valueFunctions are immutable so you can use them as dictionary keysFunctions can be the return value of another function

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 19 / 24

Page 20: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

λ (lambda) Functions

Anonymous functions are function objects without a namelambda arg: ret is the same as

def <lambda>(arg):return ret

lambdas can have the same arguments as regular functionsI lambda arg, *args, named=val, **kwargs: ret

lambdas must be one-liners and do not support annotations

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 20 / 24

Page 21: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Higher Order Functions

The most common are map, filter, and reduce(foldL)map(f, seq) returns an iterator containing each element of seqbut with f appliedfilter(f, seq) returns an iterator of the elements of seqwhere bool(f(seq[i]))is True

filter(None, seq) is the same asfilter(lambda x: x, seq)

reduce must be imported. from functools import reduce

reduce(f, seq, base)I Builds up result by calling f on elements of seq starting with baseI f(...f(f(base,seq[0]),seq[1]),...)I If base is not specified then the first argument is seq[0]I Calling reduce on an empty sequence is a TypeError

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 21 / 24

Page 22: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Functions as Keyword Args

Many functions will accept another function as a kwargsorted(seq, key=f)

I sorted will call f on the elements to determine orderI The elements in the resulting list will be the same objects in seqI Have the key return a tuple to sort multiple fields

min(seq, key=f) and max(seq, key=f) behave similarlyThis is a good spot for lambda

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 22 / 24

Page 23: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Outline

1 Function ArgumentsPositional and Named ArgumentsVariable Number of ArgumentsVariables Declared Outside Function

2 Functional ProgrammingBackgroundHigher Order FunctionsPartial Application

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 23 / 24

Page 24: CIS192: Python Programming - Functional Programmingcis192/spring2017/html/files/lec/lec3.pdfFunctional programming attempts to make it easier to reason about program behavior I Mathematical

Partial Application

Partial application creates a new function by supplying an existingfunction with some of its argumentsSay you have add(x, y): x + y

You want add_3(y): 3 + y

add_3 = add(3) raises a TypeError

add_3 = functools.partial(add, 3)

Harry Smith (University of Pennsylvania) CIS 192 Lecture 3 February 1, 2017 24 / 24