kj wrote:
In <7figv3f2m3p0...@mid.uni-berlin.de> "Diez B. Roggisch" <de...@nospam.web.de> 
writes:

Classes are not scopes.

Classes are objects. In particular, they are (by default) instances of class 'type'. Unless 'scopes' were instances of some other metaclass, the statement has to be true. I understand 'scope' as referring to a section of code, as opposed to a runtime object.

Class statements introduce a new local namespace used to define the class. Whether one considers that as introducing a new 'scope' depends, I suppose, on one's exact definition of scope.

This looks to me like a major wart, on two counts.

It is a 'wart' that a Python object is not a 'scope', whatever that is to you? I have trouble comprehending that claim.

First, one of the goals of OO is encapsulation, not only at the
level of instances, but also at the level of classes.  Your comment
suggests that Python does not fully support class-level encapsulation.

I really do not see how your claim follows from the comment. The irony of your 'two counts' is that the example of 'count 2' fails precisely because of the encapsulation that you claim does not exist as 'count 1'.

Second, my example shows that Python puts some peculiar restrictions
on recursion.

I claim it does not. Name-based recursion inherently requires that a function be able to access itself by name at the time it is called. This can be a bit tricky, especially in a language with dynamic rather than static name binding and resolution, as it requires that code within the function be able to access a scope outside itself in which the function name is defined. In other words, it requires that function code *not* be completely encapsulated. It also require that the appropriate name be used when there is one. Neither of these is a 'peculiar restriction' imposed by Python.

class Demo(object):
    def fact_rec(n):
        if n < 2:
            return 1
        else:
            return n * fact_rec(n - 1)

This function is just a function. It is not an instance method. It is not even a class method. It does not belong here and should not be here.

If you insist on putting it where it does not belong, then you have to call it by a name that works. If you only call it after the class statement has finished, then 'Demo.fact_rec' works, as I believe someone else pointed out.

If you want to call the function during class creation, before (in this case) Demo exists, then binding it to a local name works. With 3.1

class Demo:
   def f1(n):
      if n < 2: return 1
      else:     return n * Demo.f1(n - 1)

   def f2(n,f):
      if n < 2: return 1
      else:     return n * f(n - 1, f)

   cvar = f2(5, f2)

print(Demo.f1(5), Demo.cvar, Demo.f2(5,Demo.f2))

# prints
>>>
120 120 120

Recursive functions should be OK wherever functions are OK.

Iteration can and has been viewed as within-frame recursion. When iterative rather than recursive syntax is used, the naming issue is
avoided.

Is there any good reason (from the point of view of Python's overall
design) for not fixing this?

After reading the above, what, if anything, do you think still needs to be fixed?

Before 2.2, Python functions were more encapsulated than they are today in that they could only access local and global namespaces but not outer function namespaces. It would be possible to further de-encapsulate them by giving them direct access to lexically surrounding class namespaces, but this would increase the problem of name clashes without solving any real problems in proper Python code. It could also break the intentional design principle that function code should mean the same thing whether placed within or without a class statement. This principle allows functions to be added to existing classes as attributes and work as methods that same as if they had been defined with the class.

Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to