When should I write my functions in curried form? does not match my thought, need to correct myself.
As part of my learning link, this is what I understand from function currying. Below is one example:
def curry2(f):
"""Returns a function g such that g(x)(y) == f(x, y)
>>> from operator import add
>>> add_three = curry2(add)(3)
>>> add_three(4)
"""
def g(x):
def h(y):
return f(x, y)
return h
return g
In any application, if I know that the number of arguments are fixed (say 2 arguments) and
function name is normalise_range
(say), then I will define def normalise_range(x, y):
function and use it in my application directly by calling normalise_range(x, y)
.
In any application, if I know that, the number of arguments are fixed (say 2 arguments),
but the function name is varying (can be normalise_range
/average
/I don't know..),
then I will use def curry2(f):
as shown above, which will accept all functions that take two arguments (fixed).
My question:
Currying is helpful when you have to frequently call a function with a fixed argument. Considering, for example, the following function: If we want to define the function error , warn , and info , for every type, we have two options. Currying provides a shorter, concise, and more readable solution.
Python does not have an explicit syntax for Currying functions; but it does provide infrastructure that allows Curried functions to be created.
The Closure's job is to make sure that variable is preserved when the lambda escapes that context. A Curried function is a function that can take its arguments in multiple steps, or multiple different function-applications. This normally means there are lambdas nested within lambdas.
The function make curried is another example of a higher order function because it expects a function as one of its parameters. In general, any function that takes a function as at least one of its parameters or returns a function, as its result is known as a higher order function.
Currying has at-least two advantages I can think of:
1) It keeps your code (and in turn your thinking) DRY.
Say you are have a function like:
def call_me(context, args):
...
by currying you can get a specialized function for that context
which can be tossed around etc. You don't have to repeat the context again.
2) Thinking in terms of a single input function is much easier than n
arguments; this can be debatable at times though.
See also: What is the difference between currying and partial application?
The purpose of function currying is to easily get specialized functions from more general functions. You achieve this by pre-setting some parameters at a different time and keeping them fixed afterwards.
It has nothing to do with the naming. In Python you can rename a variable/function easily at all times.
Example:
def simple_function(a):
def line(b=0):
def compute(x):
return [a+b * xi for xi in x]
return compute
return line
x = range(-4, 4, 1)
print('x {}'.format(list(x)))
print('constant {}'.format(simple_function(3)()(x)))
print('line {}'.format(simple_function(3)(-2)(x)))
gives
x [-4, -3, -2, -1, 0, 1, 2, 3]
constant [3, 3, 3, 3, 3, 3, 3, 3]
line [11, 9, 7, 5, 3, 1, -1, -3]
Now this was not yet that exciting. It only replaced functions calls of type f(a,b,c)
with calls of type f(a)(b)(c)
which might even be seen as the less elegant style in Python.
But it allows you to do:
line_through_zero = simple_function(0)
print('line through zero {}'.format(line_through_zero(1)(x))) # only slope and x
which gives
line through zero [-4, -3, -2, -1, 0, 1, 2, 3]
So the advantage of currying is that you get specialized functions that have fixed parameters and can be used instead of writing the more general form and setting the parameters fixed at each single call.
Alternatives to currying are: partial
, lambda
and default parameters
. So in practice currying might be useful but you can also get around it if you want.
See also Currying in Python
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With