This is a generic question about using anonymous functions as arguments to other functions. I give an example in Python, but the question is not about Python (and I'm particularly interested in whether answers might be different for functional languages than for other paradigms).
In Python it is common to pass an anonymous function as an argument to another function, for example:
sorted(my_data_structure, key=lambda x: x.foo)
lambda x: x.foo is an anonymous function to return the
foo attribute of the 0th element of each thing in
my_data_structure (under the assumption that whatever lives in
my_data_structure will have a 0th item and that 0th item will have a
To my mind, in all but the simplest cases, this presents a problem for encapsulation and extensibility: what if
my_data_structure changes? What if the attribute to sort by becomes
bar in a later code refactoring? Now you've got to descend into the actual
lambda to deal with it.
Alternatively, this could have been written as:
def my_helper(some_data_thing): """My intentions are ____ ! """ return some_data_thing.foo #Elsewhere in the code: sorted(my_data_structure, key=my_helper)
While this adds 4 lines of code, it is more readable. You don't have to parse whatever the
lambda is trying to do at the moment you read about the call to
sorted. It gives the opportunity for type annotation, documentation, or even unit-testing to occur for the helper function.
If something changes, but you still want the local code around the use of
sorted to remain the same, this nicely encapsulates that for you away into the helper function. And if more than one place needed to sort, or group, or whatever, by the same key, you get code reuse better than reproducing the
lambda is many locations.
However, others might also say that you are bending over backwards to give a name,
my_helper, to a little function that is actually more clear to just see it in code directly.
I can agree with this to an extent, especially when the
lambda involved is very small, but what if it needs to be a multi-line
lambda that runs into a lot of indentation issues, or involves a somewhat obfuscated list comprehension or some other device?
My question is: what approaches exist for determining where to draw the line between a useful in-line anonymous function that is "self-contained" enough that it is more effective to write it directly versus an in-line function that is too complex and should be wrapped in a helper function. Are there other considerations I'm not taking into account?