10.10. Functional Order

  • Higher-order function - takes other functions as arguments and/or returns functions

  • Lower-order function - does not take other functions as arguments or return functions

Functions in the functional programming style are treated as variables. This makes them first-class functions. These can be passed to other functions as parameters or returned from functions or stored in data structures. [1]

A higher-order function is a function that takes other functions as arguments and/or returns functions. First-class functions can be higher-order functions in functional programming languages. [1]

10.10.1. Definition

>>> def increment(x):  # lower-order function
...     return x + 1
>>>
>>> def get_function():  # higher-order function
...     return increment
>>>
>>>
>>> func = get_function()
>>> func(1)
2

10.10.2. Nested

  • Function inside of a function

  • Function serves as a namespace

  • Closures will be covered in a future chapter

>>> def get_function():  # higher-order function
...     def increment(x):  # lower-order function
...         return x + 1
...     return increment
>>>
>>>
>>> func = get_function()
>>> func(1)
2

10.10.3. Use Case - 1

>>> def increment(x):
...     return x + 1
>>>
>>> def decrement(x):
...     return x - 1
>>>
>>> def get_function(operation):
...     if operation == 'bigger':
...         return increment
...     elif operation == 'smaller':
...         return decrement
>>>
>>>
>>> func = get_function('bigger')
>>> func(1)
2

10.10.4. Use Case - 2

  • fetch - higher-order function

  • ok - lower-order function

  • err - lower-order function

SetUp:

>>> from urllib.request import urlopen

Define higher-order function fetch that takes two lower-order functions on_success and on_error as arguments. The function fetches the content of a URL and calls the appropriate callback function based on the result:

>>> def fetch(url: str,
...           on_success = lambda response: ...,
...           on_error = lambda error: ...,
...           ) -> None:
...     try:
...         result = urlopen(url).read().decode('utf-8')
...     except Exception as error:
...         on_error(error)
...     else:
...         on_success(result)

Define two lower-order functions ok and err that print the response and error, respectively:

>>> def ok(response: str):
...     print(response)
>>>
>>> def err(error: Exception):
...     print(error)

Usage:

>>> fetch(url='https://python3.info', on_success=ok, on_error=err)  

10.10.5. References

10.10.6. Assignments

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Functional Callable Define
# - Difficulty: easy
# - Lines: 1
# - Minutes: 3

# %% English
# 1. Define function `run()` without any parameter
# 2. Function `run()` must return `myfunc: Callable`
# 3. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj funkcję `run()` bez żadnego parametru
# 2. Funkcja `run()` ma zwracać `myfunc: Callable`
# 3. Uruchom doctesty - wszystkie muszą się powieść

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from inspect import isfunction

>>> assert isfunction(run)
>>> assert isfunction(myfunc)
>>> assert isfunction(run())

>>> myfunc()
'hello from myfunc'

>>> run()()
'hello from myfunc'
"""


def myfunc():
    return 'hello from myfunc'


# Without any parameter
# Returns myfunc function
# type: Callable[[Callable], Callable]
def run():
    ...