Unification of Methods and Functions

Antoon Pardon apardon at forel.vub.ac.be
Fri May 14 08:29:32 EDT 2004


Op 2004-05-13, David MacQuigg schreef <dmq at gain.com>:
> On Thu, 13 May 2004 10:56:58 -0400, "Terry Reedy" <tjreedy at udel.edu>
> wrote:
>
>>"Antoon Pardon" <apardon at forel.vub.ac.be> wrote in message
>>news:slrnca6d58.1i9.apardon at trout.vub.ac.be...
>>> One could argue that all forms of methods and functions are unified.
>>> It is just that python does some magic so that the method you
>>> access from an object is not the actual function but the curried
>>> function with the object.
>>
>>My view is similar: in Python, a method is a dressed up (wrapped) function.
>>'Unification of methods and functions' reads to me like 'unification of
>>dressed-up bodies and naked bodies'.  What would that mean?  
>
> By unification, I mean making the calling sequence identical for all
> methods and functions.

It already is. It is just that the function you have defined within
the class, is not the function you call through the object.

> No more special syntax for lambda functions,

All right I understand that.

> static methods, etc.  No time wasted on these topics in a text like
> Learning Python.  A simpler presentation of OOP, based on what
> students already know at this point - functions, modules, and global
> variables.

A method is just a function. The special calling form for methods
is not object specific. With a little extra work you can have exactly
the same calling form for classes with no methods.

>>One thing I
>>like about Python is that there is only function-body syntax and not a
>>separate, slightly different method-body syntax.  To me, having only one
>>type of code body *is* unification.  So it is hard for me to see what is
>>being proposed.  
>
> The one fundamental difference between methods and functions is the
> presence of instance variables in methods.

No it is not. The instance variables you speak of within a method
are just the instance variables of a parameter. It can work just
as well with a function that is written outside the class. you
just need to wrap it somewhat if you want the same calling sequence
but that is all and this wrapping can happen outside the class too.


> You can hide that
> difference with the self.var trick.  You can hide it even further by
> not using 'self', but some other word that looks just like the other
> variable names in the function.  None of this removes the actual
> difference, or makes learning about instance variables any easier for
> the student.

Maybe you should start with classes without methods then. Just

class Whatever:
  pass.

Now you can make objects of this class, give them instance variables
and write a function that expects a whatever object as first argument
en let it play with the instance variables of the argument. If you wish
you can call that first argument self it doesn't really matter. There
is nothing method or function specific here. 

> The choice of how to identify instance variables is a minor issue.  I
> think it is actually better not to *hide* the instance variables, but
> to *highlight* them.  Ruby uses $var for instance variables.  Prothon
> uses a leading dot, which is quite visible in most code editors.
>
> The real issue is not self.var vs .var  It is the complexity resulting
> from having different calling sequences.

There really aren't different calling sequences, just to different
related function. Lets consider the two following functions.

def addf(a, b):

    return a + b


def addc(a):

  def addh(b):

    return a + b

  return addh


Now you can use both to add two numbers, but the calling sequence
will be different: You call addf(n1, n2), but you call addc(n1)(n2).
The seconde is called the curried version of the first.
Now if I know I will need to add 2 to al lot of numbers I can
do the following: add2 = addc(2) and now when I need to add 2 to
a number I can just call add2(n). So now I have a function that
has the value 2 bound to it. In a way it has become a method of
2. We can do that even explicitly

class Int(int):
    pass

two = Int(2)
add2 = addc(two)
two.add = add2

>>> two, add2(5), two.add(6), addf(two, 7)

(2, 7, 8, 9)


The only thing that is happening is that if you write a function
within a class, python transforms it into the curried version
and does the rest of the things implicitely that I have done
above explicitly.


> Compare the 96-page
> presentation of OOP in Learning Python, 2nd ed. to what I have written
> at http://ece.arizona.edu/~edatools/Python/Prototypes.doc
> In 7 pages, I can present the basics of OOP.  Adding examples and
> exercises will probably bring this to 30 pages.  The key to this
> simplification is not having to deal with unnecessary complexities,
> like lambda functions, static methods, etc.
>
>>Introducing a syntax like '.var' that would only be
>>meaningful in a method and not a function would be dis-unification.
>
> Actually, .var could be used in a function outside a class, just as
> you can now use self.var in the current function syntax.  Before using
> a function with .var, the global variable __self__ must be set. This
> is normally done by calling the function from an instance.  Before
> using a function with self.var, the first argument must be set.  This
> is normally done by calling the function fom an instance.

> To say that adding an instance variable to a function breaks unity is
> like saying that adding a global variable to a function breaks unity.

It does in some sense.

I also could have written the add2 function as follows

self = 2
def add2(n):

  return self + n


I don't think that would have been a good idea. Having __self__ being
a global variable is disaster waiting to happen. What if a method
calls another method, what if you use threads?

> Adding an instance variable to a function simply makes the function
> dependent on an external variable.  Same with a global.

But currently in python "self" is not an external variable, it is
just the first argument of the function. Manipulating an argument
is different from manipulating an external variable.

-- 
Antoon Pardon



More information about the Python-list mailing list