When Closure get external variable's value?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Huayang Xia

    When Closure get external variable's value?

    What will the following piece of code print? (10 or 15)

    def testClosure(max Index) :

    def closureTest():
    return maxIndex

    maxIndex += 5

    return closureTest()

    print testClosure(10)

    My question is when the closure function gets value for maxindex? Run
    time or compile time?

    Thanks.

  • Huayang Xia

    #2
    Re: When Closure get external variable's value?

    It will print 15. The closure gets the value at run time.

    Could we treat closure as part of the external function and it shares
    the local variable with its holder function?

    Comment

    • Jussi Salmela

      #3
      Re: When Closure get external variable's value?

      Huayang Xia kirjoitti:
      It will print 15. The closure gets the value at run time.
      >
      Could we treat closure as part of the external function and it shares
      the local variable with its holder function?
      >
      I don't quite get what you are trying to tell us but if you think that
      in your example code:

      def testClosure(max Index) :

      def closureTest():
      return maxIndex

      maxIndex += 5

      return closureTest()

      print testClosure(10)

      you are returning a callable function you are all wrong. This can be
      easily seen by:
      >>type(testClos ure(10))
      15
      <type 'int'>

      The mistake is that you shouldn't return closureTest() but closureTest
      instead. The correct way would be:
      >>def testClosure2(ma xIndex):
      def closureTest():
      return maxIndex
      maxIndex += 5
      return closureTest
      >>f2 = testClosure2(10 )
      <function closureTest at 0x00D82530>
      >>type(f2)
      <type 'function'>
      >>print f2()
      15

      Cheers,
      Jussi

      Comment

      • Huayang Xia

        #4
        Re: When Closure get external variable's value?

        Thanks for the clarification.

        But my question is:

        When does the closure get the value of the maxIndex in the following
        code snippet?

        def testClosure(max Index) :

        def closureTest():
        return maxIndex

        maxIndex += 5

        return closureTest()

        print testClosure(10)


        I thought it should be 10 instead of 15. That was wrong.

        After several tests, I found maxIndex is, though, local to
        testClosure() but is external to the closureTest(). closureTest() gets
        the value of maxIndex at run time. So that it's 15 instead of 10. The
        following snippet will verify that further:

        def testClosure1(ls t):

        def closureTest():
        lst.append(lst[-1]+1)

        lst.append(lst[-1]+1)
        return closureTest()

        alist = [1]
        testClosure1(al ist)
        alist.append(3)
        testClosure1(al ist)

        The 'lst' in function testClosure1() and the closure closureTest() are
        same thing as alist. So everything is dynamic. Variable's value is
        determined at run time.

        Comment

        • Fredrik Lundh

          #5
          Re: When Closure get external variable's value?

          Huayang Xia wrote:
          When does the closure get the value of the maxIndex in the following
          code snippet?
          >
          def testClosure(max Index) :
          >
          def closureTest():
          return maxIndex
          >
          maxIndex += 5
          >
          return closureTest()
          >
          print testClosure(10)
          >
          >
          I thought it should be 10 instead of 15. That was wrong.
          free variables in an inner scope bind to variables in the outer scope,
          not objects.

          if you want to bind to objects, use explicit binding:

          def closureTest(max Index=maxIndex) :
          return maxIndex

          </F>

          Comment

          • Huayang Xia

            #6
            Re: When Closure get external variable's value?

            That is a really concise and precise answer. Thanks.

            So the object binding can only happen explicitly at the closure
            declaration argument list(non-free variable).

            On Dec 19, 10:37 am, Fredrik Lundh <fred...@python ware.comwrote:
            Huayang Xia wrote:
            When does the closure get the value of the maxIndex in the following
            code snippet?
            >
            def testClosure(max Index) :
            >
            def closureTest():
            return maxIndex
            >
            maxIndex += 5
            >
            return closureTest()
            >
            print testClosure(10)
            >
            I thought it should be 10 instead of 15. That was wrong.free variables in an inner scope bind to variables in the outer scope,
            not objects.
            >
            if you want to bind to objects, use explicit binding:
            >
            def closureTest(max Index=maxIndex) :
            return maxIndex
            >
            </F>

            Comment

            • Marc 'BlackJack' Rintsch

              #7
              Re: When Closure get external variable's value?

              In <1166544951.721 977.281100@t46g 2000cwa.googleg roups.com>, Huayang Xia
              wrote:
              That is a really concise and precise answer. Thanks.
              >
              So the object binding can only happen explicitly at the closure
              declaration argument list(non-free variable).
              That's no declaration that's a definition and it happens at runtime! It's
              executed every time the outer function is called and executed and creates
              a function object.

              As far as I can see you don't create a closure BTW. You are *calling*
              that inner function and return the *result* of that call.

              Ciao,
              Marc 'BlackJack' Rintsch

              Comment

              • Huayang Xia

                #8
                Re: When Closure get external variable's value?

                I'm confused. What is the definition of closure.

                I'm not sure if it's correct, I get the definition from wikipedia:

                "A closure typically comes about when one function is declared entirely
                within the body of another, and the inner function refers to local
                variables of the outer function. At runtime, when the outer function
                executes, a closure is formed. It consists of the inner function's code
                and references to any variables in the outer function's scope that the
                closure needs."

                I agree it is not declaration, it's definition. However it's closure
                based on the above definition. It uses free variable. Or you mean it's
                a closure only when the outer function returns it and be exposed to
                external world?

                The code snippet was just for test purpose. My question was how the
                free variable inside inner function (the closure) binds with object.
                That was answered by Fredrik perfectly.

                Comment

                • Bruno Desthuilliers

                  #9
                  Re: When Closure get external variable's value?

                  Huayang Xia a écrit :
                  I'm confused. What is the definition of closure.
                  >
                  I'm not sure if it's correct, I get the definition from wikipedia:
                  >
                  "A closure typically comes about when one function is declared entirely
                  within the body of another, and the inner function refers to local
                  variables of the outer function. At runtime, when the outer function
                  executes, a closure is formed. It consists of the inner function's code
                  and references to any variables in the outer function's scope that the
                  closure needs."
                  You skipped the first and most important sentence:
                  "In programming languages, a closure is a function that refers to free
                  variables in its lexical context."

                  IOW, a closure is a function that carry it's own environment. In the
                  following code, the function returned by make_adder is a closure :

                  def make_adder(addi ng):
                  def adder(num):
                  return num + adding
                  return adder


                  add_three = make_adder(3)
                  print add_three(4)
                  =7
                  I agree it is not declaration, it's definition. However it's closure
                  based on the above definition. It uses free variable.
                  Actually, it uses a variable defined in the enclosing scope. But as long
                  as it's also executed in the same enclosing scope, it's just a nested
                  function.
                  Or you mean it's
                  a closure only when the outer function returns it and be exposed to
                  external world?
                  Bingo.

                  Comment

                  • Fredrik Lundh

                    #10
                    Re: When Closure get external variable's value?

                    Bruno Desthuilliers wrote:
                    >You skipped the first and most important sentence:
                    "In programming languages, a closure is a function that refers to free
                    variables in its lexical context."
                    >
                    IOW, a closure is a function that carry it's own environment.
                    in contrast to functions that don't know what environment they belong
                    to, you mean ? can you identify such a construct in Python ?

                    </F>

                    Comment

                    • Huayang Xia

                      #11
                      Re: When Closure get external variable's value?

                      My understanding was:

                      Closure is a nested function first. If it refers free variable, then it
                      is closure. If it doesn't refer free variable, it doesn't have to be
                      nested. That is probably the reason, the free variable is emphasized.
                      Normally it makes sense to return a closure, but not a non-closure
                      nested function.

                      I don't understand why while a nested function perfectly matches the
                      definition of closure, it is not closure simply because it is not used
                      by external world.

                      BTW, IMHO, The meaning of the "most important sentence" was contained
                      in the original quote. That was the reason I skipped it.

                      On Dec 19, 4:14 pm, Bruno Desthuilliers
                      <bdesth.quelque ch...@free.quel quepart.frwrote :
                      Huayang Xia a écrit :
                      >
                      I'm confused. What is the definition of closure.
                      >
                      I'm not sure if it's correct, I get the definition from wikipedia:
                      >
                      "A closure typically comes about when one function is declared entirely
                      within the body of another, and the inner function refers to local
                      variables of the outer function. At runtime, when the outer function
                      executes, a closure is formed. It consists of the inner function's code
                      and references to any variables in the outer function's scope that the
                      closure needs."You skipped the first and most important sentence:
                      "In programming languages, a closure is a function that refers to free
                      variables in its lexical context."
                      >
                      IOW, a closure is a function that carry it's own environment. In the
                      following code, the function returned by make_adder is a closure :
                      >
                      def make_adder(addi ng):
                      def adder(num):
                      return num + adding
                      return adder
                      >
                      add_three = make_adder(3)
                      print add_three(4)
                      =7
                      >
                      I agree it is not declaration, it's definition. However it's closure
                      based on the above definition. It uses free variable.Actual ly, it uses a variable defined in the enclosing scope. But as long
                      as it's also executed in the same enclosing scope, it's just a nested
                      function.
                      >
                      Or you mean it's
                      a closure only when the outer function returns it and be exposed to
                      external world?Bingo.

                      Comment

                      • Fredrik Lundh

                        #12
                        Re: When Closure get external variable's value?

                        Huayang Xia wrote:
                        I don't understand why while a nested function perfectly matches the
                        definition of closure, it is not closure simply because it is not used
                        by external world.
                        Like so many other computing terms, the word "closure" is used in
                        different ways by different people.

                        Strictly speaking, a closure is simply a function with free variables,
                        where the bindings for all such variables are known in advance. Some
                        early languages didn't have "closed" functions; the bindings for free
                        variables were left open, and was determined at runtime. And languages
                        that had both "open" and "closed" functions needed some way to
                        distinguish between the two, so people started referring to the latter
                        as "closures".

                        But in Python, as well as in most other modern languages, all functions
                        are "closed" -- i.e. there are no "open" free variables -- so the use of
                        the term has morphed from "a function for which all free variables have
                        a known binding" to "a function that can refer to environments that are
                        no longer active" (such as the local namespace of an outer function,
                        even after that function has returned). And since *that* is somewhat
                        difficult to implement, and programmers don't like to hide things that
                        are hard to implement, people still like to use the term to distinguish
                        between closed functions of kind 1 and closed functions of kind 2. As
                        in this thread, they sometimes argue that when you're using a closed
                        function of kind 2 in a specific way, it's not quite as much of a
                        closure as when you use it in another way. Heck, some people even argue
                        that languages that don't support closed functions of kind 3 (a kind
                        that Python currently doesn't support) don't really have closures at all.

                        But as a language user, you can actually forget about all this -- all
                        you need to know is that in Python, all functions are closed, and free
                        variables bind to *variable names* in lexically nested outer scopes.

                        </F>

                        Comment

                        Working...