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 = <some combination of @, sum, map, add, div, power, enumerate, ...> with parameter names omitted, it would be harder to understand. Using it would require the ability to infer argument types and order from the composed expression.
I intentionally added a statement to calculate the common subexpression prior to the return. I believe it would have to put back in the return expression before converting.