About functions


In [1]:
def square(n):
    ans = n * n
    return ans
In [2]:
square(4)
Out[2]:
16
In [3]:
def power(n, m):
    ans = 1
    for i in range(m):
        ans = ans * n
    return ans
In [4]:
power(4, 2)
Out[4]:
16
In [5]:
def square(n):
    return power(n, 2)
In [6]:
square(4)
Out[6]:
16


Map


In [7]:
# Create a list of numbers.
numbers = list(range(10))
In [8]:
numbers
Out[8]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [9]:
# Apply f to all numbers.
def mapall(f, l):
    return [f(i) for i in l]
In [10]:
# Apply square function (from above) to numbers list.
mapall(square, numbers)
Out[10]:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
In [11]:
# Apply str() function to numbers.
mapall(str, numbers)
Out[11]:
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
In [12]:
# Apply an anonymous function to numbers.
mapall(lambda x: x - 5, numbers)
Out[12]:
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]


Reduce


In [13]:
# Take a list and reduce it to a number.
# Output is ...f(f(f(l[0], l[1]), l[2]), l[3]), ...
def reduceall(f, l):
    # Start with the first element as answer.
    ans = l[0]
    # Loop through the other elements.
    for x in l[1:]:
        # Apply f to current answer and next list element.
        ans = f(ans, x)
    return ans
In [14]:
# Imperative programming languages...
def plus(x, y):
    """Replacing an operator with a function."""
    return x + y
In [15]:
numbers
Out[15]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [16]:
# Add all elements of numbers.
reduceall(plus, numbers)
Out[16]:
45
In [17]:
reduceall(plus, mapall(lambda x: x - (sum(numbers) / len(numbers)), numbers))
Out[17]:
0.0
In [18]:
numbers
Out[18]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [19]:
# A functional programming language would let you do this:
# Uncomment for an error:
# reduceall(+, numbers)
In [20]:
# Or this...
# Uncomment for an error:
# reduceall(sum, numbers)


Data as functions

In [21]:
def two():
    return 2
In [22]:
two() + two()
Out[22]:
4
In [23]:
def four():
    return two() + two()
In [24]:
four()
Out[24]:
4
In [25]:
4 + four()
Out[25]:
8
In [26]:
def four_the_func():
    return four
In [27]:
four_the_func()
Out[27]:
<function __main__.four()>
In [28]:
# Uncomment for an error:
# four_the_func() + four_the_func()


Two views of computing


Turing's view


State Read Write Move Next
$A$ 0 $1$ R $B$
$A$ 1 $0$ R $B$
$A$ _ $F$ L $ $
$B$ 0 $0$ R $A$
$B$ 1 $1$ R $A$
$B$ _ $F$ L $ $

Input: $00001111$

Workings: $A00001111 \rightarrow 1B0001111 \rightarrow 10A001111 \rightarrow \ldots$

Output: $10100101F$


Church's view


$$\lambda x. x x$$$$(\lambda x. x x) A = A A$$


$$(\lambda x. x x)(\lambda x. x x)$$$$(\lambda x. x x)(\lambda x. x x) = (\lambda x. x x)(\lambda x. x x) = \ldots$$


$$0: \qquad \lambda f. \lambda x. x$$$$1: \qquad \lambda f. \lambda x. f x$$$$Successor: \qquad \lambda n. \lambda f. \lambda x. f (n f x)$$


$$\qquad (\lambda n. \lambda f. \lambda x. f (n f x)) (\lambda f. \lambda x. x) = \lambda f. \lambda x. f x$$


Programs and files


In [29]:
import sys
In [30]:
with open(r"C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE", "rb") as f:
    for i in range(4):
        byte = f.read(1)
        ibyte = int.from_bytes(byte, byteorder=sys.byteorder)
        print(f"{ibyte:>08b}", end=" ")
01001101 01011010 10010000 00000000 
In [31]:
with open(r"C:\Users\Ian\Desktop\Hello.docx", "rb") as f:
    for i in range(4):
        byte = f.read(1)
        ibyte = int.from_bytes(byte, byteorder=sys.byteorder)
        print(f"{ibyte:>08b}", end=" ")
01010000 01001011 00000011 00000100