In Python, is it considered better style to:
- explicitly define useful functions in terms of more general, possibly internal use, functions; or,
- use partial function application to explicitly describe function currying?
I will explain my question by way of a contrived example.
Suppose one writes a function, _sort_by_scoring, that takes two arguments: a scoring function and a list of items. It returns a copy of the original list sorted by scores based on each item's position within the original list. Two example scoring functions are also provided.
def _sort_by_score(scoring, items_list):
unsorted_scored_list = [(scoring(len(items_list), item_position), item) for item_position, item in enumerate(items_list)]
sorted_list = [item for score, item in sorted(unsorted_scored_list)]
return sorted_list
def _identity_scoring(items_list_size, item_position):
return item_position
def _reversed_scoring(items_list_size, item_position):
return items_list_size - item_position
The function _sort_by_score is never called directly; instead, it is called by other single-argument functions that pass a scoring function and their lone argument (a list of items) to _sort_by_scoring and return the result.
# Explicit function definition style
def identity_ordering(items_list):
return _sort_by_score(_identity_scoring, items_list)
def reversed_ordering(items_list):
return _sort_by_score(_reversed_scoring, items_list)
Obviously, this intent is better expressed in terms of function currying.
# Curried function definition style
import functools
identity_ordering = functools.partial(_sort_by_score, _identity_scoring)
reversed_ordering = functools.partial(_sort_by_score, _reversed_scoring)
Usage (in either case):
>>> foo = [1, 2, 3, 4, 5]
>>> identity_ordering(foo)
[1, 2, 3, 4, 5]
>>> reversed_ordering(foo)
[5, 4, 3, 2, 1]
Apparent advantages of the explicit function definition style:
- useful functions may be defined before the more general functions are, without raising NameErrors;
- helper functions (e.g., scoring functions) could be defined within the function definition body;
- possibly easier to debug;
- code looks nice by virtue of "explicit is better than implicit."
Apparent advantages of curried function definition style:
- expresses intent of functional programming idiomatically;
- code looks nice by virtue of succinctness.
For defining "useful" functions, which of the two styles is preferred? Are there other styles that are more idiomatic/Pythonic/etc.?