Yet another blog, by yet another person.
Random stuff about Python, Java, Scala, and other random stuff.
apply() is Going AwayPython 3.0 will remove apply() from built-ins. What follows is a farewell party for apply().
Consider the following Python example:
def eat(staple, *sides, **drinks):
pass
def find(thing, tool="camera", bait=None):
pass
# Now we can call eat as follows:
eat("omelette", "fries", "crisps", start="soda", end="wine")
# And find as follows:
find("rat", bait="cheese")
What if we had an iterable and a dictionary with the values that need to be passed for sides and drinks, respectively? We could pick out each element and write out the whole function call. That wouldn't really work for variable length arguments, and dictionaries which are essentially optional key-value pairs.
The original solution was the apply() built-in, which was just a function to invoke a function with arguments given by an iterable and an optional dictionary.
apply()There used to be a time, when the only non-ugly way of doing this would be to use the built-in apply() as follows:
apply(eat, food_and_sides_iter, drinks_dict)
Furthermore, we had to combine the variable length sides with the initial arguments. If these were not together, we will need to combine them.
apply(eat, ("omelette",) + tuple(sides_iter), drinks_dict)
apply() FeatureThis apply feature is so handy, that language support for this feature was added. So, apply() was not really removed, it was made part of the core language. This means that, instead of using the built-in function apply() , we simply indicate that our iterable or dictionary should be unpacked.
Our earlier examples become:
eat(*food_and_sides_iter, **drinks_dict)
# and
eat("omelette", *sides_iter, **drinks_dict)
# even
eat("omelette", special_side, *sides_iter, **drinks_dict)
# just one side? just put it there
eat("omelette", just_fries, **drinks_dict)
# no sides? no problem
eat("omelette", **drinks_dict)
# no iters or dicts
eat("omelette", "fries", "pesto", start="water", end="KCN")
# even for without variable arity
find("rat", **tool_kit_dict)
As you can see, the integrated feature is much more flexible, and cleaner. You don't need to manually pack and unpack things (which is needed in some cases with the apply() built-in).
With the apply feature entrenched int the core Python language for years, and the redundant apply removed, another small clean-up was in order. Tuples will no longer be automatically unpacked in function calls.
# This won't work any more (in 3.0)
eat("omelette", sides_tuple)
# Need to do this
eat("omelette", *sides_tuple)
This is to keep the syntax regular--removing special cases where possible (as noted in the Zen of Python):
Special cases aren't special enough to break the rules.
Although practicality beats purity.
apply() Lives OnI am not sure now, if calling this a farewell party for apply() is accurate. We could view this as a welcoming party, where apply() is now in the core language and no longer standing outside as well, just in case. There is a problem with this as well, because apply feature was integrated into the language a long-long time ago. Maybe, we can call this the official induction. :-)
All that is gone is the built-in function apply(), not the feature, which is already integrated into the language.
Labels: apply(), python, python 3.0
Posted by FiniteState42i @11:55 | Permanent Link
Subscribe to
Posts [Atom]