Presentation is loading. Please wait.

Presentation is loading. Please wait.

Functional.

Similar presentations


Presentation on theme: "Functional."— Presentation transcript:

1 Functional

2 Functions as objects

3 Declarative Languages
Declarative Languages usually describe the end point first and the program works to get there. One subset of these are Functional Languages where one passes one procedure to another in ever more complex nesting in order to calculate some end result defined by the first layer of nesting. Generally stateful elements like variables are discouraged; the code is constructed from expressions rather than full statements. To return to declarative languages… some declarative languages are also Fifth Generation Languages, though frequently they are not as they involved coding. The general idea is the same though – to describe what you want to end up with, and work from that to generate the solution.

4 text = input("Type a number to add to four")
value = int(text) answer = 4 + value print (answer) print ( 4 + int( input( "Type a number to add to four“ ) Generally stateful elements like variables are discouraged; the code is constructed from expressions rather than full statements. In the above, for example (which is a functional version of the original shown in grey), we start with the fact that we want to print something, and work down adding code to generate the components of the solution. Note, in particular, that we have got rid of the stateful elements – the variables. There is not record of the answers beyond their use (so called “side effects”). This cuts out the opportunity for code elsewhere to alter the state of the solution in error, but also makes coding much harder. It doesn’t especially matter if you don’t follow this now, we will come back to it.

5 Python Functional languages are increasingly popular as everything is contained within the nesting; this means it can be split up easily so different nests run on different processors on machines with more than one processor (which is usual now) – we’ll come back to this. Python is a third generation imperative language, but with functional bits. Such hybrids are generally the direction of travel. Most languages are converging on something which is a mix of functional and imperative programming. For example, R, a functional language, comes across as very imperative, whereas Java, which is very imperative by tradition, has introduced many functional elements. Other declarative programming styles have had less effect.

6 Functional programming
In general, Python is functional-ish in places. The functional elements concentrate on the application of functions directly to e.g. sequences:

7 Functions as objects In Python, pretty much everything is an object, including functions. This means you can do this: def func(): pass a = funct a() print(a)

8 Efficiency Indeed, it is more efficient. If we do: a = B() a.c() This needs to construct a new reference to the function c each it is called. If we do this: d = a.c # Note lack of paretheses when talk about name. d() We just use the old call. Function calls are amongst the most processor intensive standard language elements, so this can make considerable savings.

9 Function 'fun' This means it is possible to assign functions to objects. (With the types library it is also possible to assign them to classes currently being used) class A(): def prt(self): print("hi") def prrrt(): print("changed") a = A() a.prt() a.prt = prrrt

10 Now I am become Death, the destroyer of prints
>>> print = 0 >>> print() TypeError: 'int' object not callable.

11 Functions Also means functions can be passed into other functions: sort (list, key=str.upper)

12 Builtins: lists map(function, iterable, …)
Applies function to iterable as an iterator: for value in map(ord, ["A","B","C"]): # ord returns ACSII numbers print(value)

13 Lambdas "headless" or "anonymous" functions: i.e. short functions without names. Can only contain expressions, not statements (e.g. variable assignments). for square in map(lambda x: x**2, [1,2,3,4,5]): print(str(square)) # 1, 4, 9, 16, 25 for added in map(lambda x,y: x+y, [1,2,3,4,5],[1,2,3,4,5]): print(str(added)) # 2, 4, 6, 8, 10 b = "fire walk with me".split(" ") for a in map(lambda x: x[::-1], b): print(a) # erif klaw htiw em Beware adding lambdas to sequences as they get added as functions, not the result of functions:

14 Reduce functools.reduce(function, iterable)
Applies function cumulatively, so: def power(a, b): return a ** b import functools c = [2,3,4,5] d = functools.reduce(power, c) # (((2*3)*4)5) print(d) or reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) # ((((1+2)+3)+4)+5) x is accumulator, y is each subsequent value. functools.update_wrapper: wraps around functions, passing in and returning parameters from another function that wraps around it.

15 Filter filter(function, sequence) filters out anything in sequence which function says is false. See also various iterators that apply functions to sequences in:

16 Decorators Enhance functions by wrapping them in code.
e.g. Least Recently Used cache: @lru_cache(maxsize=32) def get_lat_long(location): return lookup(location) for c in "Leeds", "Manchester", "Sheffield", "Liverpool", "Leeds": print(get_lat_long(c)) Saves the last 32 runs of this function for quick repeat; "memoizing" For more, see:

17 List comprehensions Essentially slightly easier and more flexible lambdas for setting up lists: listA = [1,2,3,4] listB = [2*x for x in listA] print(listB) # [2, 4, 6, 8] listB = [2* x for x in range(1:5)] print(listB) # [2, 4, 6, 8] listB = [2*x for x in listA if x % 2 == 0] # Even numbers only print(listB) # [4, 8] Can be used to apply a method to everything in a list.

18 Combinatorics List comprehensions can be used to generate combinations of values: listA = [(x, y) for x in [1,2,3] for y in ["a","b","c"]] print(listA) [(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c')] Essentially like developing tuples from nested for-each loops. For a tuple, you have to use a parenthesis here or you get a syntax error.

19 Generator expressions
Generator expressions: exactly like list comprehensions, but generate an item at a time, so more memory efficient: listA = [1,2,3,4] notListB = (2* x for x in range(1,5)) for i in notListB : print(i) # Works print(notListB) # Doesn't print contents as don't exist.

20 Scope The scope of variables created inside lambdas and list comprehesions is the function outlined, which some people like, as it doesn't create free variables slooping around the code afterwards. From the docs: “A scope is a textual region of a Python program where a namespace is directly accessible. “Directly accessible” here means that an unqualified reference to a name attempts to find the name in the namespace.” “For example, assume we want to create a list of squares, like: >>>>>> squares = [] >>> for x in range(10): ... squares.append(x**2) ... >>> squares [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] Note that this creates (or overwrites) a variable named x that still exists after the loop completes. We can calculate the list of squares without any side effects using: squares = list(map(lambda x: x**2, range(10))) or, equivalently: squares = [x**2 for x in range(10)] which is more concise and readable. A list comprehension consists of brackets containing an expression followed by a for clause, then zero or more for or if clauses. [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y] If the expression is a tuple (e.g. the (x, y) in the previous example), it must be parenthesized."

21 Generator functions def count(): a = 0 while True:
yield a # Returns control and waits next call. a = a + 1 b = count() print (next(b)) Generate infinite sequences. Must be attached to a variable so they are the same instance; this doesn't work: print (next(count())) Can also be used: for i in count(): print(i) To generate infinite counting loops. To pass values into these, see:


Download ppt "Functional."

Similar presentations


Ads by Google