4.12.1.1–4.12.1.3 - Function types, first-class values and application (Python)

4.12.1.1–4.12.1.3 - Function types, first-class values and application (Python)

Learn how a function maps inputs to outputs, why functions can themselves be values, and how applying a function differs from referring to it. Use Python to explore the ideas, then express them in the functional notation used in Paper 2.

Domain, co-domain and function types

A function associates each permitted input with one output, and its type describes the sets those inputs and outputs belong to.

Function type

For f:A→Bf:A\to B, AA is the domain, the set from which inputs are chosen, and BB is the co-domain, the set from which outputs are chosen. The function type is A→BA\to B.

Both sets contain objects of a data type. They may be restricted subsets: a function accepting a weekday name need not accept every possible string. For every input in its stated domain, a mathematical function must give exactly one output in its co-domain. Different inputs may share an output.

Suppose f:{a,b,c}→{0,1,2,3}f:\{a,b,c\}\to\{0,1,2,3\} uses the rule f(a)=0f(a)=0, f(b)=1f(b)=1, f(c)=1f(c)=1. This is a valid function: each permitted character has one integer output. Its co-domain includes 2 and 3 even though neither occurs as an output. The outputs actually reached form {0,1}\{0,1\}, often called the range or image. Do not replace the co-domain with the observed range when reading a stated type.

Another function is s:Z→Zs:\mathbb{Z}\to\mathbb{Z}, defined by s(x)=x2s(x)=x^2. Negative integers are valid inputs; negative integers are not produced, although they belong to the stated co-domain. A Python function can implement this rule, but Python does not automatically enforce a mathematical domain merely because we describe one. Validation or a stated precondition supplies that restriction when needed.

First-class function values

A first-class function can be handled as a value, so a program can choose and pass the operation it wants to perform.

First-class object

A value is first-class if it can appear in expressions, be assigned to a variable, be supplied as an argument, and be returned by a function call. Functions have these capabilities in functional languages and in imperative languages such as Python that support function values.

In Python, square refers to a function value; square(3) applies that function and produces the integer 9. Assigning rule = square gives another name to the function. Assigning rule = square(3) instead stores 9, which cannot then be called as a function.

The following program uses all four capabilities. The conditional expression selects a function, operation stores it, apply_once receives it as an argument, and choose returns it as its result. Returning square does not yet square a number.

Choose a function, then apply it

{"code":"def square(value):\n return value * value\n\ndef cube(value):\n return value * value * value\n\ndef choose(use_cube):\n return cube if use_cube else square\n\ndef apply_once(function, value):\n return function(value)\n\noperation = choose(False)\nprint(operation(3))\nprint(apply_once(operation, -2))\n","instructions":"Predict both output lines before running. Explain which names refer to functions and which calls produce integers. Then change choose(False) to choose(True), predict again and run: the selected operation should now cube each input.","files":[],"original_filename":"main.py","runtime_profile":"python-console-v1","file_mode":"fresh"}

Functions being first-class does not mean that every function behaves identically. A supplied function still needs an appropriate argument and result type. For example, an operation expecting an integer cannot automatically replace an operation expecting a list. Function values make selection and reuse possible; their types determine which combinations make sense.

Continue this lesson.

You’re previewing NovaLearn without an account. Create a free account to read the rest.

Create free account