On 5/9/2015 6:19 AM, Andrew Barnert via Python-ideas wrote:
I think there was, and still is. People keep coming up with abstract toy examples, but as soon as someone tries to give a good real example, it only makes sense with NumPy (Koos's) or with some syntax that Python doesn't have (yours), because to write them with actual Python functions would actually be ugly and verbose (my version of yours).
I don't think that's a coincidence. You didn't write "map square" because you don't know how to think in Python, but because using compose profitably inherently implies not thinking in Python. (Except, maybe, in the case of NumPy... which is a different idiom.) Maybe someone has a bunch of obvious good use cases for compose that don't also require other functions, operators, or syntax we don't have, but so far, nobody's mentioned one.
I agree that @ is most likely to be usefull in numpy's restricted context.
A composition operator is usually defined by application: f@g(x) is
defined as f(g(x)). (I sure there are also axiomatic treatments.) It
is an optional syntactic abbreviation. It is most useful in a context
where there is one set of data objects, such as the real numbers, or one
set + arrays (vectors) defined on the one set; where all function are
univariate (or possible multivariate, but that can can be transformed to
univariate on vectors); *and* where parameter names are dummies like
'x', 'y', 'z', or '_'.
The last point is important. Abbreviating h(x) = f(g(x)) with h = f @ g
does not lose any information as 'x' is basically a placeholder (so get
rid of it). But parameter names are important in most practical
contexts, both for understanding a composition and for using it.
dev npv(transfers, discount):
'''Return the net present value of discounted transfers.
transfers: finite iterable of amounts at constant intervals
discount: fraction per interval
'''
divisor = 1 + discount
return sum(tranfer/divisor**time
for time, transfer in enumerate(transfers))
Even if one could replace the def statement with
npv =