python3: 'where' keyword

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Steve Holden

    #31
    Re: python3: 'where' keyword

    Paul Rubin wrote:
    [color=blue]
    > "Carl Banks" <invalidemail@a erojockey.com> writes:
    >[color=green]
    >>When I asked you to do this, it was just a rhetorical way to tell you
    >>that I didn't intend to play this game. It's plain as day you're
    >>trying to get me to admit something. I'm not falling for it.
    >>
    >>If you have a point to make, why don't you just make it?[/color]
    >
    >
    > You asked me to compare the notion of macros with the Zen list. I did
    > so. I didn't see any serious conflict, and reported that finding.
    > Now you've changed your mind and you say you didn't really want me to
    > make that comparison after all.
    >[/color]
    Well I for one disagreed with many of your estimates of the zen's
    applicability to macros, but I just couldn't be arsed saying so.
    [color=blue]
    > An amazing amount of the headaches that both newbies and experienced
    > users have with Python, could be solved by macros. That's why there's
    > been an active interest in macros for quite a while. It's not clear
    > what the best way to do design them is, but their existence can have a
    > profound effect on how best to do these ad-hoc syntax extensions like
    > "where". Arbitrary limitations that are fairly harmless without
    > macros become a more serious pain in the neck if we have macros.
    >[/color]
    This is not a justifiable assertion, IMHO, and if you think that newbies
    will have their lives made easier by the addition of ad hoc syntax
    extensions then you and I come from a different world (and I suspect the
    walls might be considerably harder in mine than in yours).
    [color=blue]
    > So, we shouldn't consider these topics separately from each other.
    > They are likely to end up being deeply related.[/color]

    I don't really understand why, if macros are so great (and you are
    reading the words of one who was using macros back in the days of
    Strachey's GPM) why somebody doesn't produce a really useful set of
    (say) M4 macros to prove how much they'd improve Python.

    Now that's something that would be a bit less ignorable than this
    apparently interminable thread.

    regards
    Steve

    PS: Your continued use of the NOSPAM.invalid domain is becoming much
    more irritating than your opinions on macros in Python. Using a bogus
    URL is piling crap on top of more crap.
    --
    Steve Holden http://www.holdenweb.com/
    Python Web Programming http://pydish.holdenweb.com/
    Holden Web LLC +1 703 861 4237 +1 800 494 3119

    Comment

    • Paul Rubin

      #32
      Re: python3: 'where' keyword

      Steve Holden <steve@holdenwe b.com> writes:[color=blue]
      > Well I for one disagreed with many of your estimates of the zen's
      > applicability to macros, but I just couldn't be arsed saying so.[/color]

      Well, I was being somewhat flip with them, as I felt Carl was being
      snotty in referring me to the Zen list. The point there is that one
      can interpret each of the Zen points in many ways regarding macros. I
      don't feel there's a conflict between macros and the Zen list. Macros
      in Python are a deep subject and gurus have been discussing them for a
      long time. I think that with PyPy it will become easier to experiment
      with possible approaches. In other posts I've suggested a moratorium
      on new Python syntax until after PyPy is deployed.
      [color=blue][color=green]
      > > An amazing amount of the headaches that both newbies and experienced
      > > users have with Python, could be solved by macros.... It's not clear
      > > what the best way to do design them is, but their existence can have a
      > > profound effect on how best to do these ad-hoc syntax extensions like
      > > "where".[/color]
      > This is not a justifiable assertion, IMHO, and if you think that
      > newbies will have their lives made easier by the addition of ad hoc
      > syntax extensions then you and I come from a different world (and I
      > suspect the walls might be considerably harder in mine than in yours).[/color]

      I'm saying that many proposals for ad hoc extensions could instead be
      taken care of with macros. Newbies come to clpy all the time asking
      how to do assignment expressions, or conditional expressions, or
      call-by-reference. Sometimes new syntax results. Lots of times,
      macros could take care of it.
      [color=blue]
      > I don't really understand why, if macros are so great (and you are
      > reading the words of one who was using macros back in the days of
      > Strachey's GPM) why somebody doesn't produce a really useful set of
      > (say) M4 macros to prove how much they'd improve Python.[/color]

      You can't really do Python macros with something like M4. How would
      M4 even generate multi-line output that's indented to the right depth
      for the place where the macro was called? How would you write an
      m4 macro like cond(x,y,z) that does the equivalent of (x ? y : z)?
      Even if you could, it doesn't begin to address the hassle of running
      Python scripts through m4 before you can execute the scripts, especially
      in an interactive environment.

      Comment

      • Nick Coghlan

        #33
        Re: Statement local namespaces summary (was Re: python3: 'where'keyword)

        Nick Coghlan wrote:[color=blue]
        > Semantics
        > ---------
        > The code::
        >
        > <statement> with:
        > <suite>
        >
        > translates to::
        >
        > def unique_name():
        > <suite>
        > <statement>
        > unique_name()
        >[/color]

        Bleh. Not only was my proposed grammar change wrong, my suggested semantics are
        wrong, too.

        Raise your hand if you can see the problem with applying the above semantics to
        the property descriptor example.

        So I think the semantics will need to be more along the lines of "pollute the
        namespace but mangle the names so they're unique, and the programmer can *act*
        like the names are statement local".

        This will be much nicer in terms of run-time performance, but getting the
        locals() builtin to behave sensibly may be a challenge.

        Cheers,
        Nick.

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

        Comment

        • Andrey Tatarinov

          #34
          Re: Statement local namespaces summary (was Re: python3: 'where'keyword)

          Nick Coghlan wrote:[color=blue][color=green]
          >> Semantics
          >> ---------
          >> The code::
          >>
          >> <statement> with:
          >> <suite>
          >>
          >> translates to::
          >>
          >> def unique_name():
          >> <suite>
          >> <statement>
          >> unique_name()
          >>[/color]
          >
          > Bleh. Not only was my proposed grammar change wrong, my suggested
          > semantics are wrong, too.
          >
          > Raise your hand if you can see the problem with applying the above
          > semantics to the property descriptor example.
          >
          > So I think the semantics will need to be more along the lines of
          > "pollute the namespace but mangle the names so they're unique, and the
          > programmer can *act* like the names are statement local".
          >
          > This will be much nicer in terms of run-time performance, but getting
          > the locals() builtin to behave sensibly may be a challenge.[/color]

          afair you told yourself that

          var = <statement> where:
          <suite>

          translates to:

          def unique_name():
          <suite>
          return <statement>
          var = unique_name()

          in this case class gets unique_name() function? is it that bad?

          anyway I'd prefer to change semantics deeper. adding new statement-only
          scope and adding our suite-definitions there.

          Comment

          • Nick Coghlan

            #35
            Re: Statement local namespaces summary (was Re: python3: 'where'keyword)

            Nick Coghlan wrote:[color=blue]
            > Nick Coghlan wrote:
            >[color=green]
            >> Semantics
            >> ---------
            >> The code::
            >>
            >> <statement> with:
            >> <suite>
            >>
            >> translates to::
            >>
            >> def unique_name():
            >> <suite>
            >> <statement>
            >> unique_name()
            >>[/color]
            >
            > Bleh. Not only was my proposed grammar change wrong, my suggested
            > semantics are wrong, too.
            >
            > Raise your hand if you can see the problem with applying the above
            > semantics to the property descriptor example.[/color]

            Eh, never mind. The following works today, so the semantics I proposed are
            actually fine. (This is exactly the semantics proposed for the property example)

            Py> class C(object):
            .... def _x():
            .... def get(self):
            .... print "Hi!"
            .... def set(self, value):
            .... print "Hi again!"
            .... def delete(self):
            .... print "Bye"
            .... return property(get, set, delete)
            .... x = _x()
            ....
            Py> C.x
            <property object at 0x009E6738>
            Py> C().x
            Hi!
            Py> C().x = 1
            Hi again!
            Py> del C().x
            Bye

            Cheers,
            Nick.

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

            Comment

            • Nick Coghlan

              #36
              Re: Statement local namespaces summary (was Re: python3: 'where'keyword)

              Andrey Tatarinov wrote:[color=blue]
              > afair you told yourself that
              >
              > var = <statement> where:
              > <suite>
              >
              > translates to:
              >
              > def unique_name():
              > <suite>
              > return <statement>
              > var = unique_name()
              >
              > in this case class gets unique_name() function? is it that bad?[/color]

              No, I wasn't thinking clearly and saw problems that weren't there.

              However, you're right that the semantic definition should include unbinding the
              unique name after the statement finishes. E.g. for assignments:

              def unique_name():
              <suite>
              return <expr>
              <target> = unique_name()
              del unique_name
              [color=blue]
              > anyway I'd prefer to change semantics deeper. adding new statement-only
              > scope and adding our suite-definitions there.[/color]

              A new scope essentially *is* a nested function :)

              My main purpose with the nested function equivalent is just to make the intended
              semantics clear - whether an implementation actually _does_ things that way is
              immaterial.

              Cheers,
              Nick.

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

              Comment

              • Nick Coghlan

                #37
                Re: Statement local namespaces summary (was Re: python3: 'where'keyword)

                Andrey Tatarinov wrote:[color=blue]
                > I think using 'with' keyword can cause some ambiguity. for example I
                > would surely try to write
                >[color=green][color=darkred]
                > >>> x = a+b with self:
                > >>> b = member[/color][/color]
                >
                > and using with at the end of block brings more ambiguity:
                >[color=green][color=darkred]
                > >>> stmt1()
                > >>> stmt2()
                > >>> with self:
                > >>> member = stmt3()[/color][/color]
                >
                > compare to:
                >[color=green][color=darkred]
                > >>> stmt1()
                > >>> stmt2()
                > >>> with:
                > >>> variable = stmt3()[/color][/color]
                >
                > a way different semantics with just one word added/deleted.[/color]

                Except that for a "with <expr>:" block, attributes of the expression must be
                preceded by a dot:

                Py> stmt1()
                Py> stmt2()
                Py> with self:
                .... .member = stmt3()

                The advantages of the 'with' block are that 'self' is only looked up once, and
                you only need to type it once. The leading dot is still required to disambiguate
                attribute references from standard name references.

                Despite that, I think you are right that the ambiguity is greater than I first
                thought. Correct code is reasonably easy to distinguish, but in the presence of
                errors it is likely to be unclear what was intended, which would make life more
                difficult than it needs to be.

                However, I still agree with Alex that the dual life of "where" outside of Python
                (as an 'additional definitions' clause, as in mathematics, and as a
                'conditional' clause, as in SQL), and the varied background of budding
                Pythoneers is a cause for concern.

                'in' is worth considering, as it is already used by Python at least once for
                declaring use of a namespace (in the 'exec' statement). However, I suspect it
                would suffer from ambiguity problems similar to those of 'with' (consider
                "<expr> in <expr>" and "<expr> in: <expr>"). There's also the fact that the
                statement isn't *really* executed in the inner namespace - any name binding
                effects are seen in the outer scope, whereas 'exec x in dict' explicitly
                protects the containing namespace from alteration.

                So of the four keywords suggested so far ('where', 'with', 'in', 'using'), I'd
                currently vote for 'using' with 'where' a fairly close second. My vote goes to
                'using' because it has a fairly clear meaning ('execute the statement using this
                extra information'), and doesn't have the conflicting external baggage that
                'where' does.

                Cheers,
                Nick.

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

                Comment

                • Andrey Tatarinov

                  #38
                  Re: Statement local namespaces summary (was Re: python3: 'where'keyword)

                  > So of the four keywords suggested so far ('where', 'with', 'in',[color=blue]
                  > 'using'), I'd currently vote for 'using' with 'where' a fairly close
                  > second. My vote goes to 'using' because it has a fairly clear meaning
                  > ('execute the statement using this extra information'), and doesn't have
                  > the conflicting external baggage that 'where' does.[/color]

                  I should agree with you =)

                  Though I love "with" for historical reasons and addiction to functional
                  languages "using" is not that bad and I do not mind using it. =)

                  Comment

                  • Jeff Shannon

                    #39
                    Re: python3: 'where' keyword

                    Paul Rubin wrote:
                    [color=blue]
                    > Steve Holden <steve@holdenwe b.com> writes:
                    >[color=green]
                    >>[...] and if you think that
                    >>newbies will have their lives made easier by the addition of ad hoc
                    >>syntax extensions then you and I come from a different world (and I
                    >>suspect the walls might be considerably harder in mine than in yours).[/color]
                    >
                    > I'm saying that many proposals for ad hoc extensions could instead be
                    > taken care of with macros. Newbies come to clpy all the time asking
                    > how to do assignment expressions, or conditional expressions, or
                    > call-by-reference. Sometimes new syntax results. Lots of times,
                    > macros could take care of it.[/color]

                    Personally, given the requests in question, I'm extremely thankful
                    that I don't have to worry about reading Python code that uses them.
                    I don't *want* people to be able to make up their own
                    control-structure syntax, because that means I need to be able to
                    decipher the code of someone who wants to write Visual Basic as
                    filtered through Java and Perl... If I want mental gymnastics when
                    reading code, I'd use Lisp (or Forth). (These are both great
                    languages, and mental gymnastics would probably do me good, but I
                    wouldn't want it as part of my day-to-day requirements... )

                    Jeff Shannon
                    Technician/Programmer
                    Credit International

                    Comment

                    • Antoon Pardon

                      #40
                      Re: python3: 'where' keyword

                      Op 2005-01-11, Jeff Shannon schreef <jeff@ccvcorp.c om>:[color=blue]
                      > Paul Rubin wrote:
                      >[color=green]
                      >> Steve Holden <steve@holdenwe b.com> writes:
                      >>[color=darkred]
                      >>>[...] and if you think that
                      >>>newbies will have their lives made easier by the addition of ad hoc
                      >>>syntax extensions then you and I come from a different world (and I
                      >>>suspect the walls might be considerably harder in mine than in yours).[/color]
                      >>
                      >> I'm saying that many proposals for ad hoc extensions could instead be
                      >> taken care of with macros. Newbies come to clpy all the time asking
                      >> how to do assignment expressions, or conditional expressions, or
                      >> call-by-reference. Sometimes new syntax results. Lots of times,
                      >> macros could take care of it.[/color]
                      >
                      > Personally, given the requests in question, I'm extremely thankful
                      > that I don't have to worry about reading Python code that uses them.
                      > I don't *want* people to be able to make up their own
                      > control-structure syntax, because that means I need to be able to
                      > decipher the code of someone who wants to write Visual Basic as
                      > filtered through Java and Perl...[/color]

                      No you don't.

                      You could just as well claim that you don't want people to write
                      code in other languages because you then would need to be able
                      to decipher code written in that language.
                      [color=blue]
                      > If I want mental gymnastics when
                      > reading code, I'd use Lisp (or Forth). (These are both great
                      > languages, and mental gymnastics would probably do me good, but I
                      > wouldn't want it as part of my day-to-day requirements... )[/color]

                      Your day-to-day requirements are a contract between you and your
                      employer or between you and your clients. That you don't want
                      mental gymnastics as part of that, shouldn't be a concern for
                      how the language develops.

                      --
                      Antoon Pardon

                      Comment

                      • Nick Coghlan

                        #41
                        Re: Statement local namespaces summary (was Re: python3: 'where'keyword)

                        Nick Coghlan wrote:[color=blue]
                        > Semantics
                        > ---------
                        > The code::
                        >
                        > <statement> with:
                        > <suite>
                        >
                        > translates to::
                        >
                        > def unique_name():
                        > <suite>
                        > <statement>
                        > unique_name()[/color]

                        I've come to the conclusion that these semantics aren't what I would expect from
                        the construct. Exactly what I would expect can't really be expressed in current
                        Python due to the way local name bindings work. The main thing to consider is
                        what one would expect the following to print:

                        def f():
                        a = 1
                        b = 2
                        print 1, locals()
                        print 3, locals() using:
                        a = 2
                        c = 3
                        print 2, locals()
                        print 4, locals()

                        I think the least suprising result would be:

                        1 {'a': 1, 'b': 2} # Outer scope
                        2 {'a': 2, 'c': 3} # Inner scope
                        3 {'a': 2, 'b': 2, 'c': 3} # Bridging scope
                        4 {'a': 1, 'b': 2} # Outer scope

                        In that arrangement, the statement with a using clause is executed normally in
                        the outer scope, but with the ability to see additional names in its local
                        namespace. If this can be arranged, then name binding in the statement with the
                        using clause will work as we want it to.

                        Anyway, I think further investigation of the idea is dependent on a closer look
                        at the feasibility of actually implementing it. Given that it isn't as
                        compatible with the existing nested scope structure as I first thought, I
                        suspect it will be both tricky to implement, and hard to sell to the BDFL
                        afterwards :(

                        Cheers,
                        Nick.

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

                        Comment

                        • Jeff Shannon

                          #42
                          Re: Statement local namespaces summary (was Re: python3: 'where'keyword)

                          Nick Coghlan wrote:
                          [color=blue]
                          > def f():
                          > a = 1
                          > b = 2
                          > print 1, locals()
                          > print 3, locals() using:
                          > a = 2
                          > c = 3
                          > print 2, locals()
                          > print 4, locals()
                          >
                          > I think the least suprising result would be:
                          >
                          > 1 {'a': 1, 'b': 2} # Outer scope
                          > 2 {'a': 2, 'c': 3} # Inner scope
                          > 3 {'a': 2, 'b': 2, 'c': 3} # Bridging scope
                          > 4 {'a': 1, 'b': 2} # Outer scope[/color]

                          Personally, I think that the fact that the bridging statement is
                          executed *after* the inner code block guarantees that results will be
                          surprising. The fact that it effectively introduces *two* new scopes
                          just makes matters worse.

                          It also seems to me that one could do this using a nested function def
                          with about the same results. You wouldn't have a bridging scope with
                          both sets of names as locals, but your nested function would have
                          access to the outer namespace via normal nested scopes, so I'm really
                          not seeing what the gain is...

                          (Then again, I haven't been following the whole using/where thread,
                          because I don't have that much free time and the initial postings
                          failed to convince me that there was any real point...)

                          Jeff Shannon
                          Technician/Programmer
                          Credit International


                          [color=blue]
                          >
                          > In that arrangement, the statement with a using clause is executed
                          > normally in the outer scope, but with the ability to see additional
                          > names in its local namespace. If this can be arranged, then name binding
                          > in the statement with the using clause will work as we want it to.
                          >
                          > Anyway, I think further investigation of the idea is dependent on a
                          > closer look at the feasibility of actually implementing it. Given that
                          > it isn't as compatible with the existing nested scope structure as I
                          > first thought, I suspect it will be both tricky to implement, and hard
                          > to sell to the BDFL afterwards :(
                          >
                          > Cheers,
                          > Nick.
                          >[/color]

                          Comment

                          • Andrey Tatarinov

                            #43
                            Re: Statement local namespaces summary (was Re: python3: 'where'keyword)

                            Nick Coghlan wrote:[color=blue]
                            > Nick Coghlan wrote:
                            >[color=green]
                            >> Semantics
                            >> ---------
                            >> The code::
                            >>
                            >> <statement> with:
                            >> <suite>
                            >>
                            >> translates to::
                            >>
                            >> def unique_name():
                            >> <suite>
                            >> <statement>
                            >> unique_name()[/color]
                            > I've come to the conclusion that these semantics aren't what I would
                            > expect from the construct. Exactly what I would expect can't really be
                            > expressed in current Python due to the way local name bindings work. The
                            > main thing to consider is what one would expect the following to print:
                            >
                            > def f():
                            > a = 1
                            > b = 2
                            > print 1, locals()
                            > print 3, locals() using:
                            > a = 2
                            > c = 3
                            > print 2, locals()
                            > print 4, locals()
                            >
                            > I think the least suprising result would be:
                            >
                            > 1 {'a': 1, 'b': 2} # Outer scope
                            > 2 {'a': 2, 'c': 3} # Inner scope
                            > 3 {'a': 2, 'b': 2, 'c': 3} # Bridging scope
                            > 4 {'a': 1, 'b': 2} # Outer scope[/color]

                            as for me, I would expect following:

                            1 {'a': 1, 'b': 2}
                            2 {'a': 2, 'b': 2, 'c': 3'}
                            3 {'a': 2, 'b': 2, 'c': 3'}
                            4 {'a': 1, 'b': 2}

                            otherwise that would be impossible to do calculations based on scope
                            variables and "using:" would be useless =), consider example of usage:

                            current_positio n = 1
                            current_environ ment # = ...
                            current_a_lot_o f_other_paramet ers # = ...
                            scores = [count_score(mov e) for move in aviable_moves] using:
                            def count_score(mov e):
                            #walking through current_environ ment
                            return score

                            Comment

                            • Bengt Richter

                              #44
                              Re: Statement local namespaces summary (was Re: python3: 'where' keyword)

                              On Thu, 13 Jan 2005 22:41:54 +0300, Andrey Tatarinov <elephantum@dez com.mephi.ru> wrote:
                              [color=blue]
                              >Nick Coghlan wrote:[color=green]
                              >> Nick Coghlan wrote:
                              >>[color=darkred]
                              >>> Semantics
                              >>> ---------
                              >>> The code::
                              >>>
                              >>> <statement> with:
                              >>> <suite>
                              >>>
                              >>> translates to::
                              >>>
                              >>> def unique_name():
                              >>> <suite>
                              >>> <statement>
                              >>> unique_name()[/color]
                              >> I've come to the conclusion that these semantics aren't what I would
                              >> expect from the construct. Exactly what I would expect can't really be
                              >> expressed in current Python due to the way local name bindings work. The
                              >> main thing to consider is what one would expect the following to print:
                              >>
                              >> def f():
                              >> a = 1
                              >> b = 2
                              >> print 1, locals()
                              >> print 3, locals() using:
                              >> a = 2
                              >> c = 3
                              >> print 2, locals()
                              >> print 4, locals()
                              >>
                              >> I think the least suprising result would be:
                              >>
                              >> 1 {'a': 1, 'b': 2} # Outer scope
                              >> 2 {'a': 2, 'c': 3} # Inner scope
                              >> 3 {'a': 2, 'b': 2, 'c': 3} # Bridging scope
                              >> 4 {'a': 1, 'b': 2} # Outer scope[/color]
                              >
                              >as for me, I would expect following:
                              >
                              >1 {'a': 1, 'b': 2}
                              >2 {'a': 2, 'b': 2, 'c': 3'}
                              >3 {'a': 2, 'b': 2, 'c': 3'}
                              >4 {'a': 1, 'b': 2}[/color]

                              locals() doesn't automatically show everything that is visible from its local scope:
                              [color=blue][color=green][color=darkred]
                              >>> def foo():[/color][/color][/color]
                              ... a = 1
                              ... b = 2
                              ... print 1, locals()
                              ... def inner():
                              ... a = 2
                              ... c = 3
                              ... print 2, locals()
                              ... inner()
                              ... print 4, locals()
                              ...[color=blue][color=green][color=darkred]
                              >>> foo()[/color][/color][/color]
                              1 {'a': 1, 'b': 2}
                              2 {'a': 2, 'c': 3}
                              4 {'a': 1, 'b': 2, 'inner': <function inner at 0x02EE8BFC>}

                              -- unless you actually use it (this is a bit weird maybe?):
                              [color=blue][color=green][color=darkred]
                              >>> def foo():[/color][/color][/color]
                              ... a = 1
                              ... b = 2
                              ... print 1, locals()
                              ... def inner():
                              ... a = 2
                              ... c = 3
                              ... print 2, locals(), 'and b:', b
                              ... inner()
                              ... print 4, locals()
                              ...[color=blue][color=green][color=darkred]
                              >>> foo()[/color][/color][/color]
                              1 {'a': 1, 'b': 2}
                              2 {'a': 2, 'c': 3, 'b': 2} and b: 2
                              4 {'a': 1, 'b': 2, 'inner': <function inner at 0x02EE8D4C>}

                              of course a difference using the new syntax is that 'inner' is not bound to a persistent name.
                              [color=blue]
                              >
                              >otherwise that would be impossible to do calculations based on scope
                              >variables and "using:" would be useless =), consider example of usage:
                              >
                              >current_positi on = 1
                              >current_enviro nment # = ...
                              >current_a_lot_ of_other_parame ters # = ...
                              >scores = [count_score(mov e) for move in aviable_moves] using:
                              > def count_score(mov e):
                              > #walking through current_environ ment
                              > return score[/color]
                              No worry, UIAM.

                              Regards,
                              Bengt Richter

                              Comment

                              • Bengt Richter

                                #45
                                Re: Statement local namespaces summary (was Re: python3: 'where' keyword)

                                On Fri, 14 Jan 2005 01:48:48 +1000, Nick Coghlan <ncoghlan@iinet .net.au> wrote:
                                [color=blue]
                                >Nick Coghlan wrote:[color=green]
                                >> Semantics
                                >> ---------
                                >> The code::
                                >>
                                >> <statement> with:
                                >> <suite>
                                >>
                                >> translates to::
                                >>
                                >> def unique_name():
                                >> <suite>
                                >> <statement>
                                >> unique_name()[/color]
                                >
                                >I've come to the conclusion that these semantics aren't what I would expect from
                                >the construct. Exactly what I would expect can't really be expressed in current
                                >Python due to the way local name bindings work. The main thing to consider is
                                >what one would expect the following to print:
                                >
                                >def f():
                                > a = 1
                                > b = 2
                                > print 1, locals()
                                > print 3, locals() using:
                                > a = 2
                                > c = 3
                                > print 2, locals()
                                > print 4, locals()
                                >
                                >I think the least suprising result would be:
                                >
                                >1 {'a': 1, 'b': 2} # Outer scope
                                >2 {'a': 2, 'c': 3} # Inner scope
                                >3 {'a': 2, 'b': 2, 'c': 3} # Bridging scope
                                >4 {'a': 1, 'b': 2} # Outer scope
                                >
                                >In that arrangement, the statement with a using clause is executed normally in
                                >the outer scope, but with the ability to see additional names in its local
                                >namespace. If this can be arranged, then name binding in the statement with the
                                >using clause will work as we want it to.
                                >
                                >Anyway, I think further investigation of the idea is dependent on a closer look
                                >at the feasibility of actually implementing it. Given that it isn't as
                                >compatible with the existing nested scope structure as I first thought, I
                                >suspect it will be both tricky to implement, and hard to sell to the BDFL
                                >afterwards :(
                                >[/color]
                                In the timbot's let/in format:

                                def f():
                                a = 1
                                b = 2
                                print 1, locals()
                                let:
                                a = 2
                                c = 3
                                print 2, locals()
                                in:
                                print 3, locals()
                                print 4, locals()

                                I think the effect would be as if
                                [color=blue][color=green][color=darkred]
                                >>> def f():[/color][/color][/color]
                                ... a = 1
                                ... b = 2
                                ... print 1, locals()
                                ... def __unique_temp() :
                                ... a = 2
                                ... c = 3
                                ... print 2, locals()
                                ... def __unique_too():
                                ... print 3, locals()
                                ... __unique_too()
                                ... __unique_temp()
                                ... del __unique_temp
                                ... print 4, locals()
                                ...[color=blue][color=green][color=darkred]
                                >>> f()[/color][/color][/color]
                                1 {'a': 1, 'b': 2}
                                2 {'a': 2, 'c': 3}
                                3 {}
                                4 {'a': 1, 'b': 2}

                                print 3, locals() doesn't show a,b,c in locals() unless you use them
                                somehow in that scope, e.g.,
                                [color=blue][color=green][color=darkred]
                                >>> def f():[/color][/color][/color]
                                ... a = 1
                                ... b = 2
                                ... print 1, locals()
                                ... def __unique_temp() :
                                ... a = 2
                                ... c = 3
                                ... print 2, locals()
                                ... def __unique_too():
                                ... print 3, locals(), (a,b,c) # force references for locals()
                                ... __unique_too()
                                ... __unique_temp()
                                ... del __unique_temp
                                ... print 4, locals()
                                ...[color=blue][color=green][color=darkred]
                                >>> f()[/color][/color][/color]
                                1 {'a': 1, 'b': 2}
                                2 {'a': 2, 'c': 3, 'b': 2}
                                3 {'a': 2, 'c': 3, 'b': 2} (2, 2, 3)
                                4 {'a': 1, 'b': 2}

                                Of course, locals() does not include globals, even though they're
                                referenced and visible:[color=blue][color=green][color=darkred]
                                >>> b[/color][/color][/color]
                                'global b'[color=blue][color=green][color=darkred]
                                >>> def bar():[/color][/color][/color]
                                ... print locals(), b
                                ...[color=blue][color=green][color=darkred]
                                >>> bar()[/color][/color][/color]
                                {} global b

                                The trouble with this is that bindings created in __unique_too all get thrown away,
                                and you wouldn't want that limitation. So I proposed specifying the (re)bindable names
                                in a parenthesized list with the let, like "let(k, q, w): ..." so that those names
                                would be (re)bindable in the same scope as the let(...): statement.

                                As an extension, I also proposed optionally binding __unique_temp to a specified name
                                and not calling it automatically, instead of the automatic call and del.

                                That provides new ways to factor updates to local namespaces into local functions
                                with selective write-through (bind/rebind) to local names. E.g.,

                                # define case blocks for switch
                                # better sugar later, this is to demo functinality ;-)
                                #a
                                let(x):
                                k = 123
                                in foo:
                                x = k
                                #b
                                let(x, y):
                                q = 456
                                from math import pi as r
                                in bar:
                                x = q
                                y=r # extra binding created if bar is called
                                #c
                                let(x):in baz:x=789 # most compact form, where nothing in the let clause

                                switch = dict(a=foo, b=bar, c=baz)

                                Now you can update local bindings with a case switch:
                                x = 0
                                case = 'b'
                                print x # => 0
                                switch[case]() # executes bar() in this example, which assigns local x=456 and y=pi
                                print x # => 456


                                This spare example is easy to dismiss, but think of foo, bar, and baz as arbitrary sequences of statements
                                in the local namespace, except you can factor them out as a single named group and invoke them
                                safely by name(), and have them affect only the local names you specify in the group's let(x, y, ...): spec.

                                It provides a new way of factoring. As well as things no one has thought of yet ;-)

                                The other thing to think about is that the let suite could be strictly def-time, which would
                                provide the opportunity to avoid re-calculating things in functions without abusing default args,
                                and using the easy closure-variable creation instead. E.g.,

                                let(foo):
                                preset = big_calc()
                                in:
                                def foo(x):
                                return x * preset

                                (This "in:" has no "in xxx:" name, so the effect is immediate execution of the anonymously
                                defined function, which writes through to foo with the def, as permitted by let(foo):).

                                Problems? (Besides NIH, which I struggle with regularly, and had to overcome to accept Tim's
                                starting point in this ;-)

                                Regards,
                                Bengt Richter

                                Comment

                                Working...