PEP 289: Generator Expressions (please comment)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Alex Martelli

    #46
    Re: PEP 289: Generator Expressions (please comment)

    Werner Schiendl wrote:
    [color=blue]
    > Alex Martelli wrote:
    >[color=green]
    >> No, but, in all cases where the lack of parentheses would make the
    >> syntax unclear, you do need parentheses even today to denote tuples.
    >> Cfr:
    >> [1,2,3]
    >> versus
    >> [(1,2,3)]
    >> a list of three items, versus a list of one tuple.[/color]
    >
    > ok, but that's the whole point (1,2,3) *is* a tuple.[/color]

    It's a tuple in parentheses.

    The parentheses are only necessary when the syntax would otherwise
    be unclear, and THAT is the whole point.
    [color=blue][color=green][color=darkred]
    >>> x = 1, 2, 3
    >>> type(x)[/color][/color][/color]
    <type 'tuple'>

    See? "Look ma, no parentheses", because none are needed in the
    assignment to x -- the tuple, by itself, is parentheses-less,
    though people often (understandably ) put redundant parentheses
    around it anyway, just in case (so do repr and str when you
    apply them to a tuple object, again for clarity).

    Normally, tuples are indicated by commas; but when commas could
    mean something else (list displays, function calls), then you
    ALSO put parentheses around the tuple and thus clarify things
    (you also must use parentheses to indicate an EMPTY tuple,
    because there is no comma involved in that case).

    [color=blue]
    > if you want a 1-tuple in a list, you've to write
    >
    > [(1,)][/color]

    Yes, and if you write [1,] WITHOUT the parentheses, that's
    a list of one number, NOT a list of one tuple -- exactly my
    point.
    [color=blue]
    > With "similar to tuples" I meant the kind of indication that I want
    > a list with exactly one item that is a generator.[/color]

    So you parenthesize the one item to disambiguate, just like you
    would parenthesize the one item to disambiguate if the one item
    was a tuple such as
    1,
    rather than a genexp such as
    x*x for x in foo

    I.e., the proposed syntax, requiring parentheses, IS strictly
    similar to the identical requirement for parentheses in tuples
    (when either a tuple or a genexp happens to be the one item
    in a list display).

    To assign a one-item tuple to x you can write

    x = 23,

    the comma is what makes the tuple, and parentheses have nothing
    to do with the case. You can of course choose to add redundant
    parentheses, if you think they improve readability, just like
    you can generally include redundant parentheses in just about
    all kinds of expressions for exactly the same reason (e.g. you
    fear a reader would not feel secure about operator priorities).

    The difference between tuples and the proposed syntax for
    genexps is that genexp are going to _require_ parentheses
    around them -- unless the parentheses already "happen" to be
    there, i.e., in the frequent case in which the genexp is the
    only argument to a function or type call. Basically, that's
    because, even though the _compiler_ would have no problems,
    Guido judges that a _human reader_ might, in parsing

    x = y for y in foo

    as meaning

    x = (y for y in foo)

    and NOT the incorrect

    (x = y) for y in foo

    So the parentheses are mandated to make it clear beyond any
    doubt that the former, NOT the latter, parse is meant.

    [color=blue]
    > The trailing comma rule *is* there in the language already.[/color]

    A trailing comma is allowed in any "comma-separated list".
    A tuple display is a comma-separated list.
    Therefore, a tuple display allows a trailing comma.

    [A SINGLETON tuple requires a trailing comma because commas
    are what DEFINES that a tuple display is occurring -- except
    in certain contexts such as list displays and function calls,
    where the commas have another meaning, and for an empty
    tuple, where commas are -- perhaps arbitrarily -- disallowed]

    A genexp is not a comma-separated list, and has nothing to do
    with comma-separated lists, therefor it would be entirely
    arbitrary and capricious to inject commas in its syntax AT ALL.

    [color=blue]
    > Still I do not like the follwing example from the specification:
    >
    > g = (x**2 for x in range(10))
    >
    > Whatfor are the parens?[/color]

    See above: to avoid humans misparsing the unparenthesized form
    as the incorrect (g = x**2) for ...

    [color=blue]
    > To me this looks like requiring parens for
    >
    > a = b + c[/color]

    If there was any risk of humans misparsing this as the
    incorrect (a = b) + c -- then parentheses around the RHS
    might be prudent. Fortunately, in this case there is no
    such risk. Generator expressions are novel enough that
    Guido judges the risk would exist in their case, and most
    particularly since assigning a genexp to a variable will be
    extremely rare usage (could you point to a few compelling
    use cases for it...?) -- therefore it's absolutely NOT a
    bad idea to force the author of code for that rare case to
    type a couple of extra characters to make his intentions
    absolutely crystal-clear to human readers, who can easily
    be unfamiliar with that rare case and will thus be helped.

    The "a = b + c" case is exactly the opposite: it IS very
    common, therefore [1] typical readers don't need help
    parsing it because it's familiar to them AND [2] forcing
    parentheses in a very common case would be cumbersome
    (while it is not to force them in a very rare case).


    Alex

    Comment

    • Tom Evans

      #47
      Re: PEP 289: Generator Expressions (please comment)

      Raymond Hettinger wrote:[color=blue]
      >
      > Peter Norvig's creative thinking triggered renewed interest in PEP 289.
      > That led to a number of contributors helping to re-work the pep details
      > into a form that has been well received on the python-dev list:
      >
      > http://www.python.org/peps/pep-0289.html[/color]

      +1

      But to add to the naming argument, I'd like them called comprehension generators.

      ta,
      Tom

      Comment

      • Daniel Dittmar

        #48
        Re: PEP 289: Generator Expressions (please comment)

        Alex Martelli wrote:[color=blue]
        > reasonable to form the working hypothesis that you LIKE perl syntax,
        > rather than being engaged in sarcasm against your own proposals (which
        > is a form of split personality one rarely comes upon).[/color]

        I don't like list comprehension when compared to Smalltalk code blocks,
        so I was really looking for a way to keep any additional 'comprehension'
        variants limited to one syntax rule. But it seems as if the current
        trend in Python is toward succinctness. To paraphrase one poster: 'It is
        documented, therefor it is explicit'. I try to keep quiet, enjoy the
        parts of Python I like and wait for the tide to turn.

        Daniel

        Comment

        • Rocco Moretti

          #49
          Re: PEP 289: Generator Expressions (please comment)

          Alex Martelli wrote:[color=blue]
          > Werner Schiendl wrote:[color=green]
          >>Alex Martelli wrote:
          >>[color=darkred]
          >>>No, but, in all cases where the lack of parentheses would make the
          >>>syntax unclear, you do need parentheses even today to denote tuples.
          >>>Cfr:
          >>> [1,2,3]
          >>>versus
          >>> [(1,2,3)]
          >>>a list of three items, versus a list of one tuple.[/color]
          >>
          >>ok, but that's the whole point (1,2,3) *is* a tuple.[/color]
          >
          > It's a tuple in parentheses.
          >[/color]

          I've never bought the argument that "comma's make the tuple." All the
          explanations I've seen seem to be a posteriori rationalization s by
          people who are being a bit too "clever." (... no offense intended Alex.)

          I base my interpretation of this on the fact that (as I understand it)
          the comma explanation was brought up *after* the relevant semantics of
          Python were coded.

          To me, tuple packing/unpacking is a special case, not a general feature
          of tuple notation. I claim as evidence the recent c.l.p thread about
          "for d[n] in mylist:", etc. the ability to use a comma separated list in
          such situations is a special case - it isn't *really* a tuple, the fact
          that it is a tuple is an implementation detail. (Note that it may be a
          *required* implementation detail, but that's neither here or there ...)

          Of course, I'll change my opinion if Guido comes out and says that he
          consciously intended all along for tuples to be defined by commas, and
          the parenthesis were just there to disambiguate - but my guess is that
          it's instead convergent evolution of separate ad hoc devices.
          [color=blue]
          > The parentheses are only necessary when the syntax would otherwise
          > be unclear, and THAT is the whole point.[/color]

          "In the face of ambiguity, refuse the temptation to guess."

          I'd say that by allowing for some instances the ability for tuples to go
          around naked, the unparenthesized form is *still* ambiguous. The
          argument "Well, for this case it can't be a tuple, because if it *was* a
          tuple then it would be ambiguous" makes my head hurt. It seems a little
          disingenuous to define language semantics by defining what something
          *isn't*.
          [color=blue]
          > The difference between tuples and the proposed syntax for
          > genexps is that genexp are going to _require_ parentheses
          > around them -- unless the parentheses already "happen" to be
          > there, i.e., in the frequent case in which the genexp is the
          > only argument to a function or type call. Basically, that's
          > because, even though the _compiler_ would have no problems,
          > Guido judges that a _human reader_ might.[/color]

          I was going to write a big rant on the fact that I have difficulties in
          reading the genex as a "chunk", and how there should be some sort of
          bracketing required, but Guido used/uses/will use his time machine to
          deflate 9/10 of my argument.

          So let me see if I have this correct:

          (Long Answer)

          Genex's are required to have parenthesis around them except when they
          would yield double parenthesis i.e. ((...)) - and the only place where
          this is relevant is in function calls with one argument, or with
          creating a tuple. (As genex's as base class lists and as a parameter
          list would be illegal.) But with creating a tuple, you have to have a
          comma to create a singleton, so that case doesn't matter either.

          As a parenthetical (sic.) note, the only other cases of 'double
          brackets' are {(...)} and [(...)], as python doesn't use <...> as
          brackets. The first is illegal anyway - you can't create a dictionary
          with just a genex. The second is covered in the PEP - that is:

          """
          [x for x in S] # This is a list comprehension.
          [(x for x in S)] # This is a list containing one generator
          # expression.
          """
          *and* the former is depreciated in favor of list(<genex>).

          (Short Answer)

          Parenthesis are required around genex's except when they are the *only*
          parameter to a function.

          (Tuples?)

          My only other concern is with tuples without parenthesis in the single
          parameter to a function case, as they might be confused with multiple
          parameter lists.

          As I understand, the genex syntax is:

          expression1 "for" expression2 "in" expression3a
          or
          expression1 "for" expression2 "in" expression3b "if" expression4

          If expression1 is a tuple, it is required to have parenthesis. (Current
          behavior of list comprehensions. )

          If expression2 is a tuple, it can have parenthesis absent. (As it is
          delimited between for and in.) Is this the same for genex's?

          If expression3a is a tuple, it will be required to have parenthesis in
          genex's. (They are currently optional for list comps.)

          What about a tuple for expression3b? Are parenthesis required here?

          Although it doesn't really make much sense, expression4 can be a tuple.
          The PEP doesn't say, but am I correct in assuming that in such a
          condition, expression4 would require parenthesis? (Parenthesis are
          required for list comps, so I'm guessing the answer is yes.)

          (Current Final short answer)

          Parenthesis are required around genex's except when they are the *only*
          parameter to a function. If either the first or last expression in a
          genex is a tuple, they must have parenthesis around them.

          ....

          I was against genex's without brackets, but with the requirements Guido
          added, I'm not quite sure about it. My guess is that it's a "time will
          tell" situation. I'll pass the buck to Guido.

          -Rocco

          Comment

          • Chris Wright

            #50
            Re: PEP 289: Generator Expressions (please comment)

            PEP 289 proposes stuff like
            [color=blue]
            > sum(x*x for x in roots)
            > min(d.temperatu re()*9/5 + 32 for d in days)
            > Set(word.lower( ) for word in text.split() if len(word) < 5)
            > dict( (k, somefunc(k)) for k in keylist )
            > dotproduct = sum(x*y for x,y in itertools.izip( xvec, yvec))
            > bestplayer, bestscore = max( (p.score, p.name) for p in players )[/color]


            and it seems that it's been accepted.

            I meekly accept the judgement of BDFL, but have a sneaking suspicion
            that we're on the way to re-inventing the LOOP macro here!

            I can see the appeal, but fear where it might lead us ...

            cheers

            Chris Wright

            Comment

            • Alex Martelli

              #51
              Re: PEP 289: Generator Expressions (please comment)

              Rocco Moretti wrote:
              ...[color=blue]
              > I've never bought the argument that "comma's make the tuple." All the[/color]

              So how do you explain:

              x = 7,

              print type(x)

              pray?

              [color=blue]
              > To me, tuple packing/unpacking is a special case, not a general feature[/color]

              That "7," up there is no packing nor unpacking. Just a tuple.

              [color=blue]
              > Of course, I'll change my opinion if Guido comes out and says that he
              > consciously intended all along for tuples to be defined by commas, and[/color]

              Guido doesn't follow c.l.py, so if you're interested you'll have
              to ask him directly. I think he's on record as saying so, more
              than once, but can't be bothered to check -- this subthread's just
              too silly and captious.

              [color=blue]
              > So let me see if I have this correct:
              >
              > (Long Answer)
              >
              > Genex's are required to have parenthesis around them except when they
              > would yield double parenthesis i.e. ((...)) - and the only place where
              > this is relevant is in function calls with one argument, or with
              > creating a tuple. (As genex's as base class lists and as a parameter
              > list would be illegal.) But with creating a tuple, you have to have a
              > comma to create a singleton, so that case doesn't matter either.[/color]

              Right -- the "creating a tuple" wouldn't cause any double parentheses.

              [color=blue]
              > As a parenthetical (sic.) note, the only other cases of 'double
              > brackets' are {(...)} and [(...)], as python doesn't use <...> as
              > brackets. The first is illegal anyway - you can't create a dictionary
              > with just a genex. The second is covered in the PEP - that is:
              >
              > """
              > [x for x in S] # This is a list comprehension.
              > [(x for x in S)] # This is a list containing one generator
              > # expression.
              > """
              > *and* the former is depreciated in favor of list(<genex>).[/color]

              I think the spelling is "deprecated " -- and while I'd love it
              to be, I don't think it is.

              [color=blue]
              > (Current Final short answer)
              >
              > Parenthesis are required around genex's except when they are the *only*
              > parameter to a function. If either the first or last expression in a
              > genex is a tuple, they must have parenthesis around them.[/color]

              Right, AFAIK.


              Alex

              Comment

              • Rocco Moretti

                #52
                Re: PEP 289: Generator Expressions (please comment)

                Alex Martelli wrote:
                [color=blue][color=green]
                >>"""
                >>[x for x in S] # This is a list comprehension.
                >>[(x for x in S)] # This is a list containing one generator
                >> # expression.
                >>"""
                >>*and* the former is depreciated in favor of list(<genex>).[/color]
                >
                >
                > I think the spelling is "deprecated " -- and while I'd love it
                > to be, I don't think it is.[/color]

                Aha, yes.

                From dictionary.com (Quoting the American Heritage Dictionary):

                """
                de·pre·ci·ate:
                1. To lessen the price or value of.
                2. To think or speak of as being of little worth; belittle. See
                Usage Note at deprecate.

                dep·re·cate:
                1. To express disapproval of; deplore.
                2. To belittle; depreciate.

                Usage Note: The first and fully accepted meaning of deprecate is
                “to express disapproval of.” But the word has steadily encroached on the
                meaning of depreciate. It is now used, almost to the exclusion of
                depreciate, in the sense “to belittle or mildly disparage,” as in He
                deprecated his own contribution. In an earlier survey, this newer sense
                was approved by a majority of the Usage Panel.
                """

                Deprecate also has an additional technical usage entry from the Jargon File.

                And you are right on the deprecated status. Quoth the PEP:

                """
                List comprehensions will remain unchanged. For example:

                [x for x in S] # This is a list comprehension.
                [(x for x in S)] # This is a list containing one generator
                # expression.

                Unfortunately, there is currently a slight syntactic difference. The
                expression:

                [x for x in 1, 2, 3]

                is legal, meaning:

                [x for x in (1, 2, 3)]

                But generator expressions will not allow the former version:

                (x for x in 1, 2, 3)

                is illegal.

                The former list comprehension syntax will become illegal in Python 3.0,
                and should be deprecated in Python 2.4 and beyond.
                """

                I originally misread this. It should mean:
                [x for x in 1, 2, 3] - is deprecated.
                [x for x in (1, 2, 3)] - remains valid.

                -Rocco

                Comment

                • Inyeol Lee

                  #53
                  Re: PEP 289: Generator Expressions (please comment)

                  On Fri, Oct 24, 2003 at 05:42:44AM -0700, Chris Perkins wrote:[color=blue]
                  > In fact, list comprehensions themselves become redundant syntactic
                  > sugar under the new proposal:
                  >
                  > [foo(x) for x in bar] ==> list(foo(x) for x in bar)[/color]

                  Is there any plan to deprecate list comprehension when we move to
                  Python3.0? I think the advantages are;

                  1. It's just a syntactic sugar, only saves 4 chars.

                  2. It solves loop variable leaking problem of list comprehension.
                  I think it causes less confusion to remove list comprehension than
                  to change the semantics of it not to leak loop variables when 3.0 comes.

                  3. We can

                  Comment

                  • Jess Austin

                    #54
                    Re: PEP 289: universal and existential operators

                    python@rcn.com (Raymond Hettinger) wrote in message news:<5d83790c. 0310231158.6559 5858@posting.go ogle.com>...[color=blue]
                    > Peter Norvig's creative thinking triggered renewed interest in PEP 289.
                    > That led to a number of contributors helping to re-work the pep details
                    > into a form that has been well received on the python-dev list:
                    >
                    > http://www.python.org/peps/pep-0289.html
                    >
                    > In brief, the PEP proposes a list comprehension style syntax for....[/color]

                    Toward the end of the PEP, we have the following:
                    [color=blue]
                    >The utility of generator expressions is greatly enhanced when[/color]
                    combined with >reduction functions like sum(), min(), and max().
                    Separate proposals are >forthcoming that recommend several new
                    accumulation functions possibly >including: product(), average(),
                    alltrue(), anytrue(), nlargest(), nsmallest().


                    This is great. I'd like to request that alltrue() and anytrue() be
                    renamed forall() and exists(), repsectively. It would allow:

                    def prime(x):
                    return forall(x%y for y in xrange(2, math.sqrt(x)))

                    etc. This is a an opportunity to be mathematically precise, and I
                    think we should be. Python is going to have the universal and
                    existential operators in a very general syntax, so let's celebrate it
                    a little.

                    later,
                    Jess

                    Comment

                    • Jeremy Fincher

                      #55
                      Re: PEP 289: universal and existential operators

                      austin@smartobj ect.biz (Jess Austin) wrote in message news:<b3ad1da7. 0311050138.433f 3478@posting.go ogle.com>...[color=blue]
                      > This is great. I'd like to request that alltrue() and anytrue() be
                      > renamed forall() and exists(), repsectively.[/color]

                      While these are the mathematical names, I've almost always seen them
                      named "all" and "any" in the various (mostly functional) programming
                      languages I've seen them in.

                      Exists() also has the problem that to less mathematically-minded
                      people (or Perl programmers :)) it isn't exactly clear what it's
                      checking for. Certainly, one would expect a generator expressions
                      like "x%y for y in xrange(2, math.sqrt(x))" to "exist," since we can
                      see it in the code and look at it with our own eyes.

                      I think these names also read somewhat more clearly:

                      # Check if someone is yelling:
                      if all(str.isupper , line.split()):
                      print "Must be a flamewar."

                      and:

                      # Check if someone yelled at all:
                      if any(str.isupper , line.split()):
                      print "Someone yelled."

                      I believe both these examples are more easily readable with "all" and
                      "any" than they would be with "forall" and "exists."

                      Jeremy

                      Comment

                      • Alex Martelli

                        #56
                        Re: PEP 289: universal and existential operators

                        Jeremy Fincher wrote:
                        ...[color=blue]
                        > I think these names also read somewhat more clearly:
                        >
                        > # Check if someone is yelling:
                        > if all(str.isupper , line.split()):
                        > print "Must be a flamewar."
                        >
                        > and:
                        >
                        > # Check if someone yelled at all:
                        > if any(str.isupper , line.split()):
                        > print "Someone yelled."[/color]

                        I'm not sure what these calls are meant represent -- maybe an
                        interface similar to filter, i.e. a callable then a sequence?
                        The functions we're considering, whatever their names, would
                        in any case just take an iterator, so, e.g.:

                        if all(x.isupper() for x in line.split()):

                        and the like.

                        [color=blue]
                        > I believe both these examples are more easily readable with "all" and
                        > "any" than they would be with "forall" and "exists."[/color]

                        I'll pass on that. Maybe. I think I still prefer alltrue and anytrue...


                        Alex

                        Comment

                        • Jeremy Fincher

                          #57
                          Re: PEP 289: universal and existential operators

                          Alex Martelli <aleax@aleax.it > wrote in message news:<g88qb.418 190$R32.1384863 6@news2.tin.it> ...[color=blue]
                          > I'm not sure what these calls are meant represent -- maybe an
                          > interface similar to filter, i.e. a callable then a sequence?
                          > The functions we're considering, whatever their names, would
                          > in any case just take an iterator, so, e.g.:
                          >
                          > if all(x.isupper() for x in line.split()):
                          >
                          > and the like.[/color]

                          Yeah, I suppose that is the case :) I was stuck in FP mode (and
                          without-generator-expressions mode; I use those two functions in my
                          own code all the time)
                          [color=blue]
                          > I'll pass on that. Maybe. I think I still prefer alltrue and anytrue...[/color]

                          I'm afraid those names would inspire people to write code like this:

                          alltrue(bool(x) for x in someIterable)

                          I think the "true" in the function names might make people think it
                          constrains the type to be a bool, which, if it resulted in code as
                          above, would definitely be unfortunate.

                          Jeremy

                          Comment

                          • rm

                            #58
                            Re: PEP 289: universal and existential operators

                            austin@smartobj ect.biz (Jess Austin) wrote in message news:<b3ad1da7. 0311050138.433f 3478@posting.go ogle.com>...[color=blue]
                            > python@rcn.com (Raymond Hettinger) wrote in message news:<5d83790c. 0310231158.6559 5858@posting.go ogle.com>...[color=green]
                            > > Peter Norvig's creative thinking triggered renewed interest in PEP 289.
                            > > That led to a number of contributors helping to re-work the pep details
                            > > into a form that has been well received on the python-dev list:
                            > >
                            > > http://www.python.org/peps/pep-0289.html
                            > >
                            > > In brief, the PEP proposes a list comprehension style syntax for....[/color]
                            >
                            > Toward the end of the PEP, we have the following:
                            >[color=green]
                            > >The utility of generator expressions is greatly enhanced when[/color]
                            > combined with >reduction functions like sum(), min(), and max().
                            > Separate proposals are >forthcoming that recommend several new
                            > accumulation functions possibly >including: product(), average(),
                            > alltrue(), anytrue(), nlargest(), nsmallest().
                            >
                            >
                            > This is great. I'd like to request that alltrue() and anytrue() be
                            > renamed forall() and exists(), repsectively. It would allow:
                            >
                            > def prime(x):
                            > return forall(x%y for y in xrange(2, math.sqrt(x)))
                            >
                            > etc. This is a an opportunity to be mathematically precise, and I
                            > think we should be. Python is going to have the universal and
                            > existential operators in a very general syntax, so let's celebrate it
                            > a little.
                            >
                            > later,
                            > Jess[/color]


                            maybe allfalse() should be included aswell?

                            rm

                            Comment

                            • Mark Hahn

                              #59
                              Re: PEP 289: universal and existential operators

                              Python doesn't use iftrue and whentrue, so why should it use alltrue and
                              anytrue? I vote for all and any.

                              "Jeremy Fincher" <tweedgeezer@ho tmail.com> wrote in message
                              news:698f09f8.0 311051223.39271 429@posting.goo gle.com...[color=blue]
                              > Alex Martelli <aleax@aleax.it > wrote in message[/color]
                              news:<g88qb.418 190$R32.1384863 6@news2.tin.it> ...[color=blue][color=green]
                              > > I'm not sure what these calls are meant represent -- maybe an
                              > > interface similar to filter, i.e. a callable then a sequence?
                              > > The functions we're considering, whatever their names, would
                              > > in any case just take an iterator, so, e.g.:
                              > >
                              > > if all(x.isupper() for x in line.split()):
                              > >
                              > > and the like.[/color]
                              >
                              > Yeah, I suppose that is the case :) I was stuck in FP mode (and
                              > without-generator-expressions mode; I use those two functions in my
                              > own code all the time)
                              >[color=green]
                              > > I'll pass on that. Maybe. I think I still prefer alltrue and[/color][/color]
                              anytrue...[color=blue]
                              >
                              > I'm afraid those names would inspire people to write code like this:
                              >
                              > alltrue(bool(x) for x in someIterable)
                              >
                              > I think the "true" in the function names might make people think it
                              > constrains the type to be a bool, which, if it resulted in code as
                              > above, would definitely be unfortunate.
                              >
                              > Jeremy[/color]


                              Comment

                              • Erik Max Francis

                                #60
                                Re: PEP 289: universal and existential operators

                                Mark Hahn wrote:
                                [color=blue]
                                > Python doesn't use iftrue and whentrue, so why should it use alltrue
                                > and
                                > anytrue? I vote for all and any.[/color]

                                Well said.

                                --
                                Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
                                __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
                                / \ Sanity is a cozy lie.
                                \__/ Susan Sontag

                                Comment

                                Working...