reduce() anomaly?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David Eppstein

    Re: Python's simplicity philosophy

    In article <7x65hiahdp.fsf @ruckus.brouhah a.com>,
    Paul Rubin <http://phr.cx@NOSPAM.i nvalid> wrote:
    [color=blue]
    > Ville Vainio <ville.spammeha rdvainio@spamtu t.fi> writes:[color=green]
    > > I wouldn't mind Python getting more influence from functional realm,
    > > as Python seems to me to be *the* hybrid language that can pull the FP
    > > thing while still remaining practical and intuitive (and delightfully
    > > non-academic).[/color]
    >
    > Python sometimes seems to go out of its way to thrwart the use of
    > functional style. Look at list.sort returning None, for example.[/color]

    The issue here is not that it returns None, but that it changes its
    input. To be truly functional, it should return a new list and leave
    the original list unchanged. Returning None is just a helpful reminder
    that it's not functional. Of course, the functional version would often
    be less efficient...

    --
    David Eppstein http://www.ics.uci.edu/~eppstein/
    Univ. of California, Irvine, School of Information & Computer Science

    Comment

    • Paul Rubin

      Re: Python's simplicity philosophy

      David Eppstein <eppstein@ics.u ci.edu> writes:[color=blue][color=green]
      > > Python sometimes seems to go out of its way to thrwart the use of
      > > functional style. Look at list.sort returning None, for example.[/color]
      >
      > The issue here is not that it returns None, but that it changes its
      > input. To be truly functional, it should return a new list and leave
      > the original list unchanged. Returning None is just a helpful reminder
      > that it's not functional. Of course, the functional version would often
      > be less efficient...[/color]

      Hmmm, good point. Returning None is still inconvenient of course.

      Comment

      • Steve Lamb

        Re: reduce()--what is it good for? (was: Re: reduce() anomaly?)

        On 2003-11-11, Robin Becker <robin@jessikat .fsnet.co.uk> wrote:[color=blue]
        > This whole thread is reminiscent of vi vs emacs or an os war or similar.
        > It's a pity that people with a preferred style should be so dogmatic
        > that they want to remove language features to prevent others using them.[/color]

        The difference there is clear. vi vs. emacs, OS A vs. OS B are two
        completely different entities. We're talking about the same one here. That
        one has a basic philosophy.
        [color=blue]
        > The whole 'only one way to do it' concept is almost certainly wrong.[/color]

        Erm, no.
        [color=blue]
        > There should be maximal freedom to express algorithms. As others have
        > stated min, max,... sum et al are useful specialisations , but because
        > they cover 99% of the space doesn't mean that reduce is redundant.
        > -Eliminate reducespeak and control the future-ly yrs-[/color]

        You have quite a few languages you can do that in. 5+ years in Perl and
        I'm done with TIMTOWTDI, thank-you-very-much. I'm glad that in Python I don't
        have to learn several different ways to do the same basic thing. I lament
        every time I have to step into another language which has several ways to do
        the same thing and if at any time Python fits the problem space that language
        occupies perfectly (as in the case of Perl) then I advocate the hell out of
        it.

        I'm glad I no longer have to deal with 4 ways of doing a simple if
        statement. I'm glad that there are only two loop constructs; one for
        iterating over a sequence and one that runs until a condition is met. It
        means that at the core level I can read the code and immediately see what is
        going on instead of having to memorize a dozen or so specilized ways of doing
        things.

        Oddly enough it is in Python that I have had the most fun programming. It
        is in Python that I find myself not only the most expressive but the most
        elegant in my programming. In Python my code is the clearest and most
        concise. I don't for one instant feel constrained by Python. I feel
        liberated by it.

        Because as much as it helps when reading the code to only have to learn a
        minimal set of controls the same applies to writing code as well. When I
        approach a problem I don't have to agonize over "well, should I do a
        do...until(), a for(;;), a while(), or something else?" It breaks down to
        this. Is it a sequence? For. Is it a condition to be met? While. There,
        done, move along.

        --
        Steve C. Lamb | I'm your priest, I'm your shrink, I'm your
        PGP Key: 8B6E99C5 | main connection to the switchboard of souls.
        -------------------------------+---------------------------------------------

        Comment

        • Terry Reedy

          Re: Python's simplicity philosophy


          "Alex Martelli" <aleax@aleax.it > wrote in message
          news:Jj4ub.4271 8$hV.1644648@ne ws2.tin.it...[color=blue]
          > The point is that the primary meaning of "reduce" is "diminish",
          > and when you're summing (positive:-) numbers you are not diminishing
          > anything whatsoever[/color]

          Yes you are: you are reducing the number of numbers. Data reduction
          is a standard term (in US at least) for literally reducing lots of
          numbers to a fewer number of numbers, like count, sum, mean,
          sum_of_squares, variance, and/or maybe a few others. As the volumn of
          data generated by observational and experimental studies explodes,
          useful reduction becomes even more important.

          .. unless you think in terms of multidimensiona l[color=blue]
          > arrays and diminishing dimensionality,[/color]

          Reducing a dimension 1 vector to a dimension 0 number is reduction in
          both senses. But even reduction of a homogeneous array to tuple of
          statistics is reduction in number if not dimension.

          Perhaps my career in statistics and data reduction made reduce() more
          immediately obvious to me than some other people.

          Terry J. Reedy


          Comment

          • Andrew Bennetts

            Re: Too much builtins (was Re: Python's simplicity philosophy

            On Mon, Nov 17, 2003 at 02:55:11PM +0000, Alex Martelli wrote:[color=blue]
            > Terry Reedy wrote:
            >[color=green][color=darkred]
            > >> len[/color]
            > > unless made a method, keep in[/color]
            >
            > A method of every sequence and container on Earth? Eeek.[/color]

            Like __len__, you mean?

            -Andrew.


            Comment

            • Terry Reedy

              Re: Python's simplicity philosophy


              "Alex Martelli" <aleax@aleax.it > wrote in message
              news:p15ub.3400 9$9_.1358080@ne ws1.tin.it...[color=blue]
              > Terry Reedy wrote:
              >
              > Hmmm, nobody else seemed to have any problem understanding my quip,[/color]

              Among those who dared respond ...
              [color=blue]
              > including the poster at which it was directed. Let me spell it out[/color]
              for you:

              Since, as I said, your target was obscure to me, thank you...
              [color=blue]
              > a few people are attacking 'sum' and defending 'reduce'
              > because the latter is "more general".[/color]

              Oh.... so that was your target.

              Since reduce with initializer is completely general, equivalent to an
              initialized for loop (which is why I might instead call it 'induce' or
              'repeat'), and hence as or more general than max, min, range,
              enumerate, map, filter, list.count, and man other functions and
              methods, and since none of these other 'less general than reduce'
              functions have been similarly attacked that I have noticed, the
              special-case, ad-hominen-like attacks on 'sum' had mostly passed
              beneath my notice as devoid of memorable content.

              A consistent preference for either or both of 'more general' and 'only
              one way to do it' might lead us toward a very lean Python with exactly
              one general repetition-with-variation function -- either 'for'
              statements or something equivalent to reduce with required
              initializer. But I have not noticed anyone proposing that.
              [color=blue]
              > So, no, I don't think my idea of "more general" is different from
              > yours: e.g., a function that, given a sequence, returns its length
              > AND the number of times 'None' occurs as an item, is more general
              > than one which just returns the length. That does not make it in
              > any intrinsic way "necessaril y preferable" -- and THAT is my point.[/color]

              Agreed. Generic versus specific involves tradeoff and balance.

              In my garage-workshop tool set, I have perhaps 10 different general
              (adjustable) wrenches, pliers, and grips, 5 specialize (fixed-size)
              box-end wenches, and perhaps 30 sockets (both metric and 'English').
              I have used most of them except for the large sockets meant for auto
              and truck work I don't do. So I am glad to have all of them.

              Terry J. Reedy


              Comment

              • Terry Reedy

                Re: Python's simplicity philosophy


                "Alex Martelli" <aleax@aleax.it > wrote in message
                news:P75ub.4309 5$hV.1657519@ne ws2.tin.it...[color=blue]
                > Terry Reedy wrote:[color=green]
                > > Would the hypothetical
                > > results = sequence.map(fu nc x: x+23)
                > > be any better?[/color]
                >
                > Just replacing the keyword 'lambda' with 'func'? If you were
                > designing a green-field language, and couldn't find any other way
                > to express callable literals -- so it only came down to a 2-way
                > choice between lambda and func as keywords with the same semantics,
                > I guess I would suggest func as the lesser evil.[/color]

                If such a change were plausibly within the boundaries changes allowed
                for the as-yet hypothetical 3.0 (or 3000), and there were not a more
                radical change that I preferred, I might seriously propose this.
                Upgrading would be simple than most other code-break changes.
                [color=blue][color=green]
                > > How about a very hypothetical (post ``==repr deprecation)
                > > results = sequence..map(` x+23`)[/color]
                >
                > How would this notation imply that x is an argument rather than,
                > say, a global?[/color]

                The above was a minimal 'concept' proposal to test the aesthetics of
                something structurally different from current 'lambda's. I think I
                would make all identifiers params by default, since I believe this to
                be more common, and 'tag' non-locals, perhaps with one of the
                reserved, as yet unused symbols. Example: lambda x: x + y == `x + @y`
                or `x+y@`. Since expressions cannot assign, no global declaration is
                needed.

                Terry


                Comment

                • Donn Cave

                  Re: Python's simplicity philosophy

                  Quoth Ville Vainio <ville.spammeha rdvainio@spamtu t.fi>:
                  ....
                  | I was merely arguing that 'reduce' is not more readable or intuitive
                  | than 'sum', which was the argument of OP.

                  My point is that readability and intuition depend on acquired
                  experience. Your non-programmer girlfriend lacks enough experience
                  to be able to understand all kinds of stuff in Python, so she's not
                  a useful gauge, because at that level you can't use Python anyway.
                  It isn't that simple, and I don't think there really is any good
                  evidence for what is readable. We could talk about why someone might
                  think reduce is about readability, but it can only be speculation.

                  | I wouldn't mind Python getting more influence from functional realm,
                  | as Python seems to me to be *the* hybrid language that can pull the FP
                  | thing while still remaining practical and intuitive (and delightfully
                  | non-academic).

                  Python may be a hybrid, but certainly none of its parents were FPLs.
                  Trying to make it one gives both Python and FP a bad name. If you
                  want a language that really supports both functional and procedural
                  styles, I think you need Lisp. Look at Dylan, I haven't tried it but
                  it may be quite a bit more comfortable for Python and C programmers.

                  Donn Cave, donn@drizzle.co m

                  Comment

                  • Georgy Pruss

                    Re: Too much builtins (was Re: Python's simplicity philosophy

                    Maybe, it's worth to have str(x,8) and str(x,16) instead of oct(x) and hex(x)
                    and make str() a true inverse function to int()?
                    G-:
                    --
                    a='a=;print a[:2]+chr(39)+a+chr( 39)+a[2:]';print a[:2]+chr(39)+a+chr( 39)+a[2:]


                    Comment

                    • Georgy Pruss

                      Re: reduce()--what is it good for? (was: Re: reduce() anomaly?)


                      "Steve Lamb" <grey@despair.d miyu.org> wrote in message news:slrnbrio3f .s51.grey@dmiyu .org...
                      | <..>
                      | Because as much as it helps when reading the code to only have to learn a
                      | minimal set of controls the same applies to writing code as well. When I
                      | approach a problem I don't have to agonize over "well, should I do a
                      | do...until(), a for(;;), a while(), or something else?" It breaks down to
                      | this.

                      I can't agree here. I NEVER wondered which of constructions should I
                      use in any particular case. I just solved the problem and wrote its solution
                      in that language and the language HELPED me to express myself clearly.

                      | Is it a sequence? For. Is it a condition to be met? While. There,
                      | done, move along.

                      Aha. Half of all the conditions in real Python programs are 1 or True. :-)

                      | --
                      | Steve C. Lamb | I'm your priest, I'm your shrink, I'm your
                      | PGP Key: 8B6E99C5 | main connection to the switchboard of souls.
                      | -------------------------------+---------------------------------------------

                      --
                      Georgy Pruss
                      E^mail: 'ZDAwMTEyMHQwMz MwQGhvdG1haWwuY 29t\n'.decode(' base64')


                      Comment

                      • Andrew Dalke

                        Re: Python's simplicity philosophy

                        Paul Rubin:[color=blue]
                        > The change was that native lists will implement stable sort. My gripe
                        > is that if native lists are required to sort stably and list-alikes
                        > can sort unstably, then list.sort and listalike.sort act differently
                        > in a way that can lead to subtle bugs.[/color]
                        ...[color=blue][color=green]
                        > > That's a statement only that list.sort shall be stable and
                        > > not that all .sort() methods must be stable.[/color]
                        >
                        > It would be icky if some .sort() methods are required to be stable but
                        > others are not.[/color]

                        I've been thinking about this. I'm of two minds about it, both
                        for and against.

                        The 'for' side, which dominates, says that the only extra work is
                        for those people who implement a version of Python. There will
                        only be few of these, and the work needed to implement at least
                        a rough cut at a stable sort is pretty minimal. Any user of a list-alike
                        sort who is concerned about its stability or wants the code to work
                        for pre-2.3 will use the DSU idiom. People who don't know about
                        differences in how sort algorithms handle ties will have their sorts
                        work "as expected".

                        The 'against' side says, as you do, that having list.sort required
                        to be stable now places an extra barrier to anyone else who
                        implements a list-alike sort, because that sort should now also
                        be stable.

                        What mollifies the latter view is that some user-defined sorts
                        won't have ties, so there will never be a problem. And some
                        user-defined sorts will want a stable sort -- anything which
                        sorts rows based on a column in a grid display must be stable.
                        So there are only going to be a relatively few cases where
                        this will be a problem.

                        Besides, what I really want is a set of algorithms implemented
                        independent of the container so that I can have a generic
                        'sort' function work on a user-defined container. At that
                        point it would be trivial for a user-defined list-alike to
                        implement its .sort() method as a call to the stable-sort
                        algorithm, which further reduces the number of times when
                        the expectation of a stable sort causes a problem.

                        Hmmm.. To do this nicely would seem to require a
                        'swap' method on lists as otherwise there's a lot of
                        movements when swapping two items in a list.
                        [color=blue]
                        > Note that the most obvious way to implement sort() in C is to call the
                        > standard C library qsort function, which is unstable.[/color]

                        And again I note that I've seen commercial software which
                        made the expectation that C's qsort(3C) was ... well, not
                        stable, but it assumed it would give the same results on
                        different machines. That error was fixed by implementing
                        their own sort algorithm. (It wasn't caught for years because
                        there are very few ties in their data and even fewer people
                        moved data from one platform to another.)

                        My preference is for a stable sort. It works the right way
                        for most cases, and no sort algorithm is going to do the
                        right thing for all cases. (Hence the explosion of sort
                        variants you rightly pointed out.)

                        Andrew
                        dalke@dalkescie ntific.com


                        Comment

                        • Andrew Dalke

                          Re: Python's simplicity philosophy

                          Terry Reedy:[color=blue]
                          > Perhaps my career in statistics and data reduction made reduce() more
                          > immediately obvious to me than some other people.[/color]

                          I know when I first saw reduce, in Python BTW, I did not
                          intuit that meaning. I was in physics grad school and
                          with a bachelor's in math, with an emphasis in analysis, so
                          my math background was pretty strong. (Though nowadays
                          I look through my books and wonder that I actual knew
                          all that once upon a time... *sigh*)

                          Andrew
                          dalke@dalkescie ntific.com


                          Comment

                          • Ville Vainio

                            Re: Python's simplicity philosophy

                            "Donn Cave" <donn@drizzle.c om> writes:
                            [color=blue]
                            > Python may be a hybrid, but certainly none of its parents were FPLs.
                            > Trying to make it one gives both Python and FP a bad name. If you[/color]

                            I don't think there is much "trying to make Python a FPL" involved w/
                            making lots of tried-and-true FPL constructs available in Python. It's
                            just taking stuff that works and enabling us to use it w/o encumbering
                            the language (because it's in the modules). It's all good as long as
                            we don't go the way of doing everything w/ recutrsion.
                            [color=blue]
                            > want a language that really supports both functional and procedural
                            > styles, I think you need Lisp. Look at Dylan, I haven't tried it but
                            > it may be quite a bit more comfortable for Python and C programmers.[/color]

                            Lisp is too verbose for my tastes (I don't want to write 'let' ot
                            'setq'), doesn't have much in the way of libs and generally doesn't
                            feel as 'right' as Python (I do use Emacs Lisp occasionally,
                            though.. and will try out some CL one of these days). Dylan, OTOH,
                            doesn't seem to be all that active a project, at least the last time I
                            checked.

                            --
                            Ville Vainio http://www.students.tut.fi/~vainio24

                            Comment

                            • Andrew Dalke

                              Re: Too much builtins (was Re: Python's simplicity philosophy

                              Georgy Pruss:[color=blue]
                              > Maybe, it's worth to have str(x,8) and str(x,16) instead of oct(x) and[/color]
                              hex(x)[color=blue]
                              > and make str() a true inverse function to int()?[/color]

                              What then are the results of
                              str(30+44j, 16)
                              str(3.1415926, 8)
                              str([9, 8, 7], 8)
                              str("A", 16)
                              str({"A": 20}, 16)
                              ?

                              Andrew
                              dalke@dalkescie ntific.com


                              Comment

                              • Georgy Pruss

                                Re: Python's simplicity philosophy


                                "Terry Reedy" <tjreedy@udel.e du> wrote in message news:sIqdnYBZtK IYFiSi4p2dnA@co mcast.com...
                                |
                                | "Alex Martelli" <aleax@aleax.it > wrote in message
                                | news:P75ub.4309 5$hV.1657519@ne ws2.tin.it...
                                | <...>
                                |
                                | > > How about a very hypothetical (post ``==repr deprecation)
                                | > > results = sequence..map(` x+23`)
                                | >
                                | > How would this notation imply that x is an argument rather than,
                                | > say, a global?
                                |
                                | The above was a minimal 'concept' proposal to test the aesthetics of
                                | something structurally different from current 'lambda's. I think I
                                | would make all identifiers params by default, since I believe this to
                                | be more common, and 'tag' non-locals, perhaps with one of the
                                | reserved, as yet unused symbols. Example: lambda x: x + y == `x + @y`
                                | or `x+y@`. Since expressions cannot assign, no global declaration is
                                | needed.
                                |
                                | Terry

                                Or maybe
                                lambda x: x + y == `x: x + y`

                                G-:


                                Comment

                                Working...