This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Jason.Baker
Recipients Jason.Baker, eric.araujo, rhettinger
Date 2011-01-26.00:34:06
SpamBayes Score 0.0
Marked as misclassified No
Message-id <1296002048.21.0.378658284085.issue11011@psf.upfronthosting.co.za>
In-reply-to
Content
Ray,  thanks for prompt and thorough feedback.  To address your concerns:

* I'm fine with doing away with const and identity (long story short I haven't really used them in functional languages anyway).  There were reasons for defining identity the way it is, but it's hardly a big deal if that doesn't make it in.
* Personally, I see the mathematical notation for compose to be very intuitive, however it's typically described in a non-intuitive manner.  The functions get called in a left-to-right manner (as is intuitive), however, when you see it defined it is usually in a right-to-left manner.  Thus it can be confusing because we say compose(f, g)(x) [left-to-right]  is equivalent to g(f(x)) [which reads right-to-left, but is still doing what you might expect intuitively].  But I doubt most people that use Python will care about the mathematical usage anyway.  What if we called  the function "pipeline"?  That's essentially what it's doing, and I think people would find that easier to understand.
* I'm not saying you're wrong about trampoline, but I want to make sure that you and I are discussing the same thing.  :-)  The idea for trampoline comes from clojure, which is unique among functional languages in that it has no tail-call recursion.  Trampoline is a way to write a function that is tail recursive, but won't blow the stack.  So your example, while similar isn't *quite* the same thing.  The documentation I wrote shows an example function count_to_a_million.  If I wrote it like this I'd blow the stack:

    def count_to_a_million(i):
        if i < 1000000:
            return count_to_a_million(i)
        else:
            return i

Of course, you could definitely argue that it would just be easier to use a loop (or even better range).  However, many functional programmers' brains have just been wired to use recursion which they might find more intuitive as a means of iteration.  Of course, one could argue that it would be better for them to learn the Pythonic way of doing things, and I would agree.  Python is a multi-paradigm language that supports both functional and imperative approaches, therefore it's Pythonic to provide a functional approach.
* It sounds like you feel flip is useful, but it's a matter of whether you feel it's useful enough to add to the standard library.

Lastly, I love list comprehensions and see where you're coming from, but why do the two have to be mutually exclusive?  I mean, the idea for them came from Haskell which hasn't done away with them.  For instance, take your example:

    [f(g(2,x), h(x, 3, y, flag=True)) for x, y in zip(X, Y) if x>y//2]

I certainly hope you don't really write code like that.  :-)

I think something like this is more readable:

    fg = partial(compose(f, g), 2)
    h1 = lambda x, y:  h(x, 3, y, flag=True)
    [(fg(x), h1(x, y)) for x, y in zip(X, Y) if x>y//2]

...but maybe I'm weird.

If you're still opposed to adding these functions, let me know.  I feel that they have use-cases in the Python standard library, but I can add them to pysistence when I port it to Python 3 and make it a functional data structure/algorithm library.  :-)
History
Date User Action Args
2011-01-26 00:34:08Jason.Bakersetrecipients: + Jason.Baker, rhettinger, eric.araujo
2011-01-26 00:34:08Jason.Bakersetmessageid: <1296002048.21.0.378658284085.issue11011@psf.upfronthosting.co.za>
2011-01-26 00:34:06Jason.Bakerlinkissue11011 messages
2011-01-26 00:34:06Jason.Bakercreate