python3: 'where' keyword

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andrey Tatarinov

    #1

    python3: 'where' keyword

    Hi.

    It would be great to be able to reverse usage/definition parts in
    haskell-way with "where" keyword. Since Python 3 would miss lambda, that
    would be extremly useful for creating readable sources.

    Usage could be something like:
    [color=blue][color=green][color=darkred]
    >>> res = [ f(i) for i in objects ] where:
    >>> def f(x):
    >>> #do something[/color][/color][/color]

    or
    [color=blue][color=green][color=darkred]
    >>> print words[3], words[5] where:
    >>> words = input.split()[/color][/color][/color]

    - defining variables in "where" block would restrict their visibility to
    one expression

    - it's more easy to read sources when you know which part you can skip,
    compare to
    [color=blue][color=green][color=darkred]
    >>> def f(x):
    >>> #do something
    >>> res = [ f(i) for i in objects ][/color][/color][/color]

    in this case you read definition of "f" before you know something about
    it usage.
  • Steven Bethard

    #2
    Re: python3: 'where' keyword

    Andrey Tatarinov wrote:[color=blue]
    > Hi.
    >
    > It would be great to be able to reverse usage/definition parts in
    > haskell-way with "where" keyword. Since Python 3 would miss lambda, that
    > would be extremly useful for creating readable sources.
    >
    > Usage could be something like:
    >[color=green][color=darkred]
    > >>> res = [ f(i) for i in objects ] where:
    > >>> def f(x):
    > >>> #do something[/color][/color]
    >
    > or
    >[color=green][color=darkred]
    > >>> print words[3], words[5] where:
    > >>> words = input.split()[/color][/color]
    >
    > - defining variables in "where" block would restrict their visibility to
    > one expression[/color]

    How often is this really necessary? Could you describe some benefits of
    this? I think the only time I've ever run into scoping problems is with
    lambda, e.g.

    [lambda x: f(x) for x, f in lst]

    instead of

    [lambda x, f=f: for x, f in lst]

    Are there other situations where you run into these kinds of problems?
    [color=blue]
    > - it's more easy to read sources when you know which part you can skip,
    > compare to
    >[color=green][color=darkred]
    > >>> def f(x):
    > >>> #do something
    > >>> res = [ f(i) for i in objects ][/color][/color]
    >
    > in this case you read definition of "f" before you know something about
    > it usage.[/color]

    Hmm... This seems very heavily a matter of personal preference. I find
    that your where clause makes me skip the 'res' assignment to read what
    the 'res' block contains. I had to read it twice before I actually
    looked at the list comprehension. Of course, I'm sure I could be
    retrained to read it the right way, but until I see some real benefit
    from it, I'd rather not have to.


    TOOWTDI-ily-yrs,

    Steve

    Comment

    • Steven Bethard

      #3
      Re: python3: 'where' keyword

      Steven Bethard wrote:[color=blue]
      > How often is this really necessary? Could you describe some benefits of
      > this? I think the only time I've ever run into scoping problems is with
      > lambda, e.g.
      >
      > [lambda x: f(x) for x, f in lst]
      >
      > instead of
      >
      > [lambda x, f=f: for x, f in lst][/color]

      Sorry, bad example, this should have looked something more like:

      [lambda y: f(x, y) for x, f in lst]

      ....

      [lambda y, x=x, f=f: f(x, y) for x, f in lst]

      where you actually need the lambda.

      Steve

      Comment

      • Donn Cave

        #4
        Re: python3: 'where' keyword

        In article <xdCdnUz9muXfT0 PcRVn-vg@comcast.com> ,
        Steven Bethard <steven.bethard @gmail.com> wrote:[color=blue]
        > Andrey Tatarinov wrote:[/color]
        [color=blue][color=green]
        > > It would be great to be able to reverse usage/definition parts in
        > > haskell-way with "where" keyword. Since Python 3 would miss lambda, that
        > > would be extremly useful for creating readable sources.
        > >
        > > Usage could be something like:
        > >[color=darkred]
        > > >>> res = [ f(i) for i in objects ] where:
        > > >>> def f(x):
        > > >>> #do something[/color]
        > >
        > > or
        > >[color=darkred]
        > > >>> print words[3], words[5] where:
        > > >>> words = input.split()[/color]
        > >
        > > - defining variables in "where" block would restrict their visibility to
        > > one expression[/color]
        >
        > How often is this really necessary? Could you describe some benefits of
        > this? I think the only time I've ever run into scoping problems is with
        > lambda, e.g.
        >
        > [lambda x: f(x) for x, f in lst]
        >
        > instead of
        >
        > [lambda x, f=f: for x, f in lst]
        >
        > Are there other situations where you run into these kinds of problems?[/color]

        Note that he says "would be extremely useful for creating readable
        sources", so the "these kinds of problems" he would have been thinking
        of would be where source was not as readable as it could be. You seem
        to be concerned about something else.

        I don't by any means agree that this notation is worth adopting, and
        in general I think this kind of readability issue is more or less a lost
        cause for a language with Python's scoping rules, but the motive makes
        sense to me. One way to look at it might be, if I observe that "words"
        is assigned to in a where clause, then I know it will not be used
        elsewhere in the surrounding scope so I can forget about it right away.
        If the name does occur elsewhere, it evidently refers to something else.

        Donn Cave, donn@u.washingt on.edu

        Comment

        • AdSR

          #5
          Re: python3: 'where' keyword

          Andrey Tatarinov wrote:[color=blue]
          > Hi.
          >
          > It would be great to be able to reverse usage/definition parts in
          > haskell-way with "where" keyword. Since Python 3 would miss lambda, that
          > would be extremly useful for creating readable sources.
          >
          > Usage could be something like:
          >[color=green][color=darkred]
          > >>> res = [ f(i) for i in objects ] where:
          > >>> def f(x):
          > >>> #do something[/color][/color][/color]

          I don't know haskell, but it looks SQL-ish to me (only by loose
          association). And it's not that unpythonic - it resembles
          [color=blue][color=green][color=darkred]
          >>> res = [x for x in sequence if x.isOk()][/color][/color][/color]
          [color=blue]
          > or
          >[color=green][color=darkred]
          > >>> print words[3], words[5] where:
          > >>> words = input.split()[/color][/color][/color]

          Here's a shorter version:
          [color=blue][color=green][color=darkred]
          >>> print input.split()[3:5:2][/color][/color][/color]

          (Does it qualify as obfuscated Python code? :) )
          [color=blue]
          > - defining variables in "where" block would restrict their visibility to
          > one expression
          >
          > - it's more easy to read sources when you know which part you can skip,[/color]

          Yes, I like the readability of it, too.
          [color=blue]
          > compare to
          >[color=green][color=darkred]
          > >>> def f(x):
          > >>> #do something
          > >>> res = [ f(i) for i in objects ][/color][/color]
          >
          > in this case you read definition of "f" before you know something about
          > it usage.[/color]

          When I first read your post, I thought "Well, just one more of those
          Py3k ideas that appear on c.l.py every day." But as I look at the latter
          example, I think you have just scratched my itch. The same thing has
          bugged me more than once in my code.

          I think this idea is of the same kind as the @decorator syntax. Guido
          moved an operation to a point in the code where it was more visible. You
          moved an operation to a more local context where (pun not intended) it
          really belongs.

          I'm usually rather conservative about Python syntax (@decorators,
          absolute/relative imports, if-else operator), but this one could appear
          in Python tomorrow and that would be too far in the future for me ;)

          Cheers,

          AdSR

          Comment

          • Paul Rubin

            #6
            Re: python3: 'where' keyword

            Donn Cave <donn@u.washing ton.edu> writes:[color=blue]
            > I don't by any means agree that this notation is worth adopting, and
            > in general I think this kind of readability issue is more or less a lost
            > cause for a language with Python's scoping rules, but the motive makes
            > sense to me.[/color]

            But we're talking about the mythical/hypothetical Python 3, so maybe
            there's a chance of fixing the scoping rules, which it seems to me are
            currently pretty badly broken.

            Comment

            • Nick Coghlan

              #7
              Re: python3: 'where' keyword

              Andrey Tatarinov wrote:[color=blue]
              > Hi.
              >
              > It would be great to be able to reverse usage/definition parts in
              > haskell-way with "where" keyword. Since Python 3 would miss lambda, that
              > would be extremly useful for creating readable sources.
              >
              > Usage could be something like:
              >[color=green][color=darkred]
              > >>> res = [ f(i) for i in objects ] where:
              > >>> def f(x):
              > >>> #do something[/color][/color][/color]

              Hmm, this is actually a really interesting idea. Avoiding accidental namespace
              conflicts is certainly one of the advantages of using lambdas.

              This idea has the virtue of being able to do the same thing, but have full
              access to Python's function syntax and assignment statements in the 'expression
              local' suite.

              In fact, any subexpressions in a complicated expression can be extracted and
              named for clarity without fear of screwing up the containing namespace, which
              would be an enormous boon for software maintainers.

              It also allows the necessary but uninteresting setup for an expression to be
              moved "out of the way", bringing the expression that does the real work to
              prominence.

              From the interpreter's point of view, the meaning would probably be something like:

              namespace = locals()
              exec where_suite in globals(), namespace
              exec statement in globals(), namespace
              res = namespace["res"]
              del namespace

              Making the 'where' clause part of the grammar for the assignment statement
              should be enough to make the above example parseable, too.

              The clause might actually make sense for all of the simple statement forms in
              the grammar which contain an expression:
              expression statement
              assignment statement
              augmented assignment statement
              del statement
              print statement
              return statement
              yield statement
              raise statement
              exec statement

              The clause really isn't appropriate for break, continue, import or global
              statements, as they don't contain any expressions :)

              For compound statements, a where clause probably isn't appropriate, as it would
              be rather unclear what the where clause applied to.

              Cheers,
              Nick.

              --
              Nick Coghlan | ncoghlan@email. com | Brisbane, Australia
              ---------------------------------------------------------------

              Comment

              • Paul Rubin

                #8
                Re: python3: 'where' keyword

                Nick Coghlan <ncoghlan@iinet .net.au> writes:[color=blue][color=green]
                > > Usage could be something like:[color=darkred]
                > > >>> res = [ f(i) for i in objects ] where:
                > > >>> def f(x):
                > > >>> #do something[/color][/color]
                >
                > Hmm, this is actually a really interesting idea. Avoiding accidental
                > namespace conflicts is certainly one of the advantages of using lambdas.[/color]

                I like it too. Seems a little perl-ish, but what the hey.
                [color=blue]
                > In fact, any subexpressions in a complicated expression can be
                > extracted and named for clarity without fear of screwing up the
                > containing namespace, which would be an enormous boon for software
                > maintainers.[/color]

                Sure, why not:

                x = (-b + sqrt(discrimina nt))/(2*a) where:
                discriminant = b*b - 4*a*c

                Maybe you could just have a where: suite that binds variables
                within the suite:

                where:
                def f(x):
                #do something
                res = [ f(i) for i in objects ]

                where:
                discriminant = b*b - 4*a*c
                x = (-b + sqrt(discrimina nt))/(2*a)

                Syntax is
                where:
                suite
                statement

                the suite has its own scope so any variable created there is local to
                the suite plus the following statement. The scope vanishes after the
                statement.

                Comment

                • Nick Coghlan

                  #9
                  Re: python3: 'where' keyword

                  Nick Coghlan wrote:[color=blue]
                  > It also allows the necessary but uninteresting setup for an expression
                  > to be moved "out of the way", bringing the expression that does the real
                  > work to prominence.[/color]

                  Killer app for this keyword:

                  class C(object):

                  x = property(get, set) where:
                  def get(self):
                  return "Silly property"
                  def set(self, val):
                  self.x = "Told you it was silly"

                  Cheers,
                  Nick.

                  --
                  Nick Coghlan | ncoghlan@email. com | Brisbane, Australia
                  ---------------------------------------------------------------

                  Comment

                  • Nick Coghlan

                    #10
                    Re: python3: 'where' keyword

                    Paul Rubin wrote:[color=blue]
                    > the suite has its own scope so any variable created there is local to
                    > the suite plus the following statement. The scope vanishes after the
                    > statement.[/color]

                    The second part of the idea is to give the statement greater prominence and
                    'hide' the uninteresting setup (the contents of the where clause).

                    Putting the statement of interest after the where suite still gives the benefits
                    of avoiding namespace clutter, but doesn't really help readability (it makes it
                    worse, if you ask me).

                    Particularly, what if the next statement is a compound statement?

                    Cheers,
                    Nick.

                    --
                    Nick Coghlan | ncoghlan@email. com | Brisbane, Australia
                    ---------------------------------------------------------------

                    Comment

                    • michele.simionato@gmail.com

                      #11
                      Re: python3: 'where' keyword

                      [color=blue]
                      > But we're talking about the mythical/hypothetical Python 3, so maybe
                      > there's a chance of fixing the scoping rules, which it seems to me[/color]
                      are[color=blue]
                      > currently pretty badly broken.[/color]

                      I don't think the current scoping rules will be changed in Python 3.0.
                      I can't give you the link right now, but there are threads about the
                      scope rules in
                      python-dev, with various people protesting and Guido saying that he
                      wants to
                      keep them as they are.

                      Michele Simionato

                      Comment

                      • Carl Banks

                        #12
                        Re: python3: 'where' keyword

                        Nick Coghlan wrote:[color=blue]
                        > Andrey Tatarinov wrote:[color=green]
                        > > Hi.
                        > >
                        > > It would be great to be able to reverse usage/definition parts in
                        > > haskell-way with "where" keyword. Since Python 3 would miss lambda,[/color][/color]
                        that[color=blue][color=green]
                        > > would be extremly useful for creating readable sources.
                        > >
                        > > Usage could be something like:
                        > >[color=darkred]
                        > > >>> res = [ f(i) for i in objects ] where:
                        > > >>> def f(x):
                        > > >>> #do something[/color][/color]
                        >[/color]
                        [snip][color=blue]
                        > For compound statements, a where clause probably isn't appropriate,[/color]
                        as it would[color=blue]
                        > be rather unclear what the where clause applied to.[/color]

                        Right. But you know that as soon as you add this to simple
                        expressions, a bunch of people are going to come here whining about how
                        they don't get to use where with if-expressions.

                        Frankly, they might have a point here. Although we have replacing
                        lambda expressions on our minds, I have in mind a different problem
                        that a where-statement would solve perfectly. But it would have to be
                        used with an if-expression.

                        However, I think it might not be so hard. Let's take Paul Rubin's
                        advice and precede the if statement with where. Let's also allow
                        "elif" clauses to be replaced with "else where ... if" clauses. That
                        which is bound in the while-block would be visible in both the
                        if-expression and if-block.

                        Then we could do this:

                        .. where:
                        .. m = someregexp.matc h(somestring)
                        .. if m:
                        .. blah blah blah
                        .. else where:
                        .. m = someotherregexp .match(somestri ng)
                        .. if m:
                        .. blah blah blah

                        We might want to spell "else where" instead as "elwhere", to match
                        "elif", but that's not important now. This would take away one of the
                        major minor annoyances of Python. (In fact, I've suggested something
                        like this as a solution to the set-and-test idiom, which Python makes
                        difficult, only I used the keyword "suppose" instead of "where".)

                        Ok, but if you do that, now you have people whining that "where" comes
                        after some expressions, and before others. (This would not bother me
                        one bit, BTW, but I'm pretty sure I'd lose the popular vote on this
                        one.)

                        So, let's go all out and say that while could precede any statement.
                        We now have consistency. Well, that really wouldn't work for the
                        if-statement, though, because then how could we apply a different
                        while-block to an else clause? We'd have to treat if-statements
                        specially anyways. So we don't have consistency.

                        My solution would be to propose two different where statements: a
                        where...do statement, and a separate where...if statement. The
                        where...do statement would look like this:

                        .. where:
                        .. def whatever(): pass
                        .. do:
                        .. blah blah use whatever blah

                        It has the advantage of being able to apply the where bindings to
                        several statements, and is, IMO, much cleaner looking than simply
                        applying where's bindings to the single following unindented statement.

                        I would recommend against where...while and where...for statements.
                        They can't accomplish anything you couldn't do with a break statement
                        inside the block, and it's not obvious whether the where clause gets
                        executed once or for each loop (since it's physically outside the loop
                        part).

                        One question: what do you do with a variable bound inside a while-block
                        that has the same name as a local variable? (Or, horrors, a
                        surrounding while-block?) I'm inclined to think it should be illegal,
                        but maybe it would be too restrictive.
                        Anyways, I like this idea a lot.

                        +1


                        --
                        CARL BANKS

                        Comment

                        • Nick Coghlan

                          #13
                          Re: python3: accessing the result of 'if'

                          Carl Banks wrote:[color=blue]
                          > Right. But you know that as soon as you add this to simple
                          > expressions, a bunch of people are going to come here whining about how
                          > they don't get to use where with if-expressions.
                          >
                          > Frankly, they might have a point here. Although we have replacing
                          > lambda expressions on our minds, I have in mind a different problem
                          > that a where-statement would solve perfectly. But it would have to be
                          > used with an if-expression.[/color]

                          I have a different suggestion for this.

                          'as' is used for renaming in import statements. 'as' will be used for exception
                          naming in Python 3k.

                          So let's use it for expression naming in 'if' statements, too.

                          if someregexp.matc h(s) as m:
                          # blah using m
                          elif someotherregexp .match(s) as m:
                          # blah using m

                          Cheers,
                          Nick.

                          --
                          Nick Coghlan | ncoghlan@email. com | Brisbane, Australia
                          ---------------------------------------------------------------

                          Comment

                          • Paul Rubin

                            #14
                            Re: python3: accessing the result of 'if'

                            Nick Coghlan <ncoghlan@iinet .net.au> writes:[color=blue]
                            > So let's use it for expression naming in 'if' statements, too.
                            >
                            > if someregexp.matc h(s) as m:
                            > # blah using m
                            > elif someotherregexp .match(s) as m:
                            > # blah using m[/color]

                            Certainly an improvement over what we have now.

                            Comment

                            • AdSR

                              #15
                              Re: python3: 'where' keyword

                              Nick Coghlan wrote:[color=blue]
                              >
                              > Killer app for this keyword:
                              >
                              > class C(object):
                              >
                              > x = property(get, set) where:
                              > def get(self):
                              > return "Silly property"
                              > def set(self, val):
                              > self.x = "Told you it was silly"[/color]

                              Hey, this is super-elegant!

                              AdSR

                              Comment

                              Working...