[Edu-sig] implementing summation notation (in Scheme & Python)

Kirby Urner pdx4d@teleport.com
Mon, 04 Jun 2001 10:06:30 -0700


>And a non-recursive version:
>
>   def sum2(term, a, next, b):
>	total = 0
>	while a<b: 

Should have been while a <= b or not a > b, as a may indeed 
equal b on the final loop.  I had that in the version of sum2 
actually running at the command line, which confuses things 
further, as anyone who cuts and pastes my code won't get the 
same result.  Such is life.

                        *       *       *

In doing this post, I discovered what I consider rather strange
behavior in the nested scopes department and posted about it to
comp.lang.python.  Here's a copy of that post.  Maybe someone here
can help rationalize this behavior:

=========


I don't get why the following two functions, each with internal
functions that take advantage of lexical scoping (new in 2.1),
behave so differently:

  from __future__ import nested_scopes

  def spam(a,b):
      def bar():
          output = []
          print b
          print a
          output.append(a+1)
          return output
      return [x for x in bar()]

  def foo(a,b):
      def bar():
          output = []
          print b
          print a
          a += 1
          output.append(a)
          return output
      return [x for x in bar()]

  >>> spam(1,10)
  10
  1
  [2]
  >>> foo(1,10)
  10
  Traceback (most recent call last):
    File "<pyshell#16>", line 1, in ?
      foo(1,10)
    File "d:\program files\python21\ocn\test.py", line 38, in foo
      return [x for x in bar()]
    File "d:\program files\python21\ocn\test.py", line 34, in bar
      print a
  UnboundLocalError: local variable 'a' referenced before assignment

I can fix foo() by assigning a to s and doing the increment on s:

  def foo(a,b):
      def bar():
          output = []
          print b
          print a
          s = a   # added this line
          s += 1 # added this line
          output.append(s)
          return output
      return [x for x in bar()]

But should a=a+1 (or a += 1) really break the initial binding of a 
to the outer scope?  Is this intended?  Given a and b initialize to
the outer scope values just fine in spam(), it seems odd to unbind
an already initialized variable at "compile time" just because we 
add 1 to it.  Seems too subtle for its own good.  a=a+1 would seem 
a runtime operation on a variable that is already initialized at 
compile time thanks to lexical scoping.

Kirby

CC replies/insights to pdx4d@teleport.com and/or above address please

=========