noob question: "TypeError" wrong number of args

B

Bruno Desthuilliers

Edward Elliott a écrit :
Will do, if nothing else it will eliminate language barriers, which we may
be running into at this point (though you've indicated otherwise).

You won't regret it anyway - my own experience is that you must go thru
this to really take full advantage of Python's power, expressivity and
flexibility.

Oh, and, yes : it's definitively fun too !-)
I appreciate your
patience and willingness to engage in this discussion.

<humble>
Votre serviteur, Messire.
As a last ditch effort to get my point across:

Compiler, interpreter, magic-codey-runny-thingy, whatever, at some point
something has to translate this source code
def method (self, a, b): something
into a function object (or whatever you're calling the runnable code this
week).

AFAIK, this is done by partly by the compiler and partly by the interpreter.
Call this translator Foo. Whatever Foo is, it can insert 'self'
into the parameter list for method,

This would have to happen before compilation - I'd say at parsing time.
But then, constructs like:

class Obj(object):
def method(...): ...
method = staticmethod(method)

or it's newer syntactic-sugar-version would become somewhat more
difficult to parse properly - but I admit that this is beyond my knowledge.
e.g. when it sees "def method (a,b)"

This has to be in a class statement - else it's shouldn't be touched.
it
pretend like it saw "def method (self,a,b)" and proceed as usual. Once it
does that, everything is exactly the same as before.

I can prove that assertion too: make a simple text processor that reads
Python source code and outputs the same source code with only one change:
insert the string 'self" as the first parameter of every "def somemethod".

Not so simple: you have plain functions (outside class statements), and
inner functions (inside def statements), and classmethods, and statict
methods, and some other corner cases (like __new__()) to take into
acccount... As I said, this requires more than a simple pre-processor
and so would have to be done at parsing time since it requires parsing
anyway. I don't know enough about Python's parser to tell if it could
work and how hard this would be.
Next run the output source code with the normal Python interpreter.
Everything functions *exactly* as before because the code is *exactly* the
same as what you would have written if you'd put the 'self's in there
manually. Now make the Python interpreter invoke this text processor as
the first step in processing source code. Voila, python + implicit self.

cf above.
No changes to the object model.
seems not.
No changes to dynamic binding. idem

Same "runnable" code as before.
seems so.
Where is the problem in this scheme?
Or (since I haven't read up on the object model yet) simply: Is there a
problem?

Apart from the added complexity to the parser, I don't find one righ now
- but note that there may as well be something obviously wrong that I
fail to spot (it's very late here and I had a hard day !-). I of course
don't take into account the fact that this would break all existing
Python code, which is unavoidable for such a syntactic change.

Well, I must admit that done this way (which is quite different from
what I understood from your previous posts), this could *perhaps*
(unless I missed something - any guru around here ?) work. At least it
does not sound so crazy.

Now is this something good is another point. I was about to argue that I
don't like the implicitness of it, but 1/ this is how most OOPLs do (at
least from a syntactic POV) and 2/ the fact is that the instance is
implicitely passed at call time, so I guess I'm just way too intoxicated
by so many years of Python programming to feel at ease with this !-)

Since Python 3K is supposed to be the 'clean the warts and don't bother
breaking compat' rewrite of Python, you may as well propose a PEP on
this. You'll have to really prove it doesn't break anything else in the
object model, have strong and articulate arguments to support your point
(like proving this is really a common source of confusion for newbies),
and I really doubt it'll be accepted anyway. But what...

Ok, time to bed now - I'll re-read this when my one and only neuron left
will be willing and able to do its job !-)
 
B

Bruno Desthuilliers

Ben Finney a écrit :
So now you're proposing that this be a special case when a function is
declared by that particular syntax, and it should be different to when
a function is created outside the class definition and added as a
method to the object at run-time.

Thus breaking not only "explicit is better than implicit",

This one can be subject to discussion. Actually, we must explicitely
declare the instance in the params list, but it's implicitely passed at
calltime by the method descriptor.
but also
"special cases aren't special enough to break the rules".

Yeps, I think this is what I don't like here.
Still -1.

I'm not yet ready to vote for Edward's proposition - as you say, it
makes 'def statements into a class statement' a special case, and I
don't like special cases too much (OTOH, there actually *are* special
cases - __new__() being an example) - *but* it's not that silly either
IMHO, and I think this should not be dismissed on a purely reactional basis.

IOW, let's give Edward some time to come up with enough rope so we can
hang him to the nearest (AS) Tree !-)
 
B

bruno at modulix

Bruno Desthuilliers wrote:
(snip)
Since Python 3K is supposed to be the 'clean the warts and don't bother
breaking compat' rewrite of Python, you may as well propose a PEP on
this. You'll have to really prove it doesn't break anything else in the
object model, have strong and articulate arguments to support your point
(like proving this is really a common source of confusion for newbies),

And of course propose an implementation - perhaps the compiler.ast could
be useful ?
 
E

Edward Elliott

Bruno said:
But then, constructs like:

class Obj(object):
def method(...): ...
method = staticmethod(method)

or it's newer syntactic-sugar-version would become somewhat more
difficult to parse properly - but I admit that this is beyond my
knowledge.

Hmm, that'll take some thought. I assume if you're making method static,
you don't declare a self parameter for it? If so, it shouldn't be hard,
just have the parser mark the method as static or no as it parses, and when
it reaches the end of the class insert 'self' for non-static methods. If a
normal method can be converted to a static method outside the class
definition, that case should work just as it does now.

This has to be in a class statement - else it's shouldn't be touched.

Exactly, that's why I called it method and not func. If you're declaring
methods outside the class and adding them dynamically, I think you would
need to declare 'self' explicitly. I'm ok with this because 1) when you're
going that route, an explicit signal that something "different" is
happening is a good thing, and 2) I have no problem with optimizing for the
common case. Not everyone will agree on these points, obviously.
Not so simple: you have plain functions (outside class statements), and
inner functions (inside def statements), and classmethods, and statict
methods, and some other corner cases (like __new__()) to take into
acccount...

Well I'm assuming the rules for when to put 'self' in the parameter list are
simple enough to be automated. In cases where they're not (e.g. dynamic
methods outside a class), I have no problem with an explicit self to signal
what's going on. That's the price you pay for dynamism.
As I said, this requires more than a simple pre-processor
and so would have to be done at parsing time since it requires parsing
anyway.

I think you could make a go of it with regular expressions, but yes parsing
is the better approach.
- but note that there may as well be something obviously wrong that I
fail to spot
ditto

(it's very late here and I had a hard day !-). I of course
don't take into account the fact that this would break all existing
Python code, which is unavoidable for such a syntactic change.

of course, which I'm sure means it will never happen, Python 3
notwithstanding.

Well, I must admit that done this way (which is quite different from
what I understood from your previous posts),

That's my fault, I did a lot of hand-waving at first and probably
contradicted myself a couple times as I was describing the idea.

Now is this something good is another point. I was about to argue that I
don't like the implicitness of it, but 1/ this is how most OOPLs do (at
least from a syntactic POV) and 2/ the fact is that the instance is
implicitely passed at call time, so I guess I'm just way too intoxicated
by so many years of Python programming to feel at ease with this !-)

I'm sure much ink will be (and has been) spilled on the subject.
Since Python 3K is supposed to be the 'clean the warts and don't bother
breaking compat' rewrite of Python, you may as well propose a PEP on
this.

Maybe that will be my summer project. We'll see, I was really hoping to
write fewer briefs and more code.
You'll have to really prove it doesn't break anything else in the
object model, have strong and articulate arguments to support your point
(like proving this is really a common source of confusion for newbies),
and I really doubt it'll be accepted anyway. But what...

It's definitely an uphill battle and I wonder if it's really worth the
effort. We'll see.
 
E

Edward Elliott

bruno said:
And of course propose an implementation - perhaps the compiler.ast could
be useful ?

Ugh. Just when I thought I'd seen my last abstract syntax tree, one rears
its ugly head.
 
B

bruno at modulix

Edward said:
Hmm, that'll take some thought. I assume if you're making method static,
you don't declare a self parameter for it?

Nope. But classmethods takes the class object as the first param
(usually named 'cls').
Exactly, that's why I called it method and not func.

Technically, they are still function objects. They are later wrapped
into method descriptor objects (at lookup time IIRC, but ask a guru or
read the doc to know for sure). And don't forget the case of nested
functions...
If you're declaring
methods outside the class and adding them dynamically, I think you would
need to declare 'self' explicitly.

Of course. Virtually *any* function can be set as a method[1] outside
the class statement scope, either directly on the class object or - with
manual wrapping - on an individual instance. And it's important to keep
this feature.

(snip)
Well I'm assuming the rules for when to put 'self' in the parameter list are
simple enough to be automated.

They are still complex enough to require a real parser. And anyway,
since this is a syntax change, this should be handled by the parser IMHO.

(snip)
It's definitely an uphill battle and I wonder if it's really worth the
effort.

Honestly, I don't think it has much chance. I barely even notice typing
'self' or 'cls', and I guess it's the same for most Python programmers
- those who can't stand it probably use another language... And FWIW, I
still prefer to keep consistency in functions definitions.
 
E

Edward Elliott

bruno said:
Technically, they are still function objects. They are later wrapped
into method descriptor objects (at lookup time IIRC, but ask a guru or
read the doc to know for sure). And don't forget the case of nested
functions...

I don't see how nested functions change anything. If they're nested in a
method, they can access self, but the name mapping is done at runtime.
Unless you mean a nested fucntion which is dynamically added as a method,
but that's the same case as the next one.

If you're declaring
methods outside the class and adding them dynamically, I think you would
need to declare 'self' explicitly.

Of course. Virtually *any* function can be set as a method[1] outside
the class statement scope, either directly on the class object or - with
manual wrapping - on an individual instance. And it's important to keep
this feature.

I wouldn't dream otherwise.
They are still complex enough to require a real parser. And anyway,
since this is a syntax change, this should be handled by the parser IMHO.

I agree, but it's good to keep options in mind.
Honestly, I don't think it has much chance. I barely even notice typing
'self' or 'cls', and I guess it's the same for most Python programmers
- those who can't stand it probably use another language... And FWIW, I
still prefer to keep consistency in functions definitions.

I have no doubt that's true for a lot of people. Hell I probably prefer the
current approach because 1) it's not a big deal in practice, and 2) I can
use the shorter 'me' or 's' in place of self in my own code, which I
couldn't do under the change (well, I could add 'me = self' as the first
statement of any method, but that's clumsy). My objections stem more from
an elegance standpoint. Of course elegance is in the eye of the beholder.
 
M

Marc 'BlackJack' Rintsch

Edward Elliott said:
I can prove that assertion too: make a simple text processor that reads
Python source code and outputs the same source code with only one change:
insert the string 'self" as the first parameter of every "def somemethod".
Next run the output source code with the normal Python interpreter.
Everything functions *exactly* as before because the code is *exactly* the
same as what you would have written if you'd put the 'self's in there
manually. Now make the Python interpreter invoke this text processor as
the first step in processing source code. Voila, python + implicit self.

Okay, let's start with writing a simple text processor for this little
mess::

def b(c):
def d(r, *s, **t):
print '***'
c(r, *s, **t)
return d


class A:
@b
def a(x, y, z):
print y, z
x.e(23)

def e(u, v):
print u, v

class B:
def e(v, w):
print 'spam', v, w

A.e = e
x = A()
x.a('answer', 42)
e('eric', 'viking')
A.a(x, 'ham', 'eggs')

Ciao,
Marc 'BlackJack' Rintsch
 
B

Ben Finney

Edward Elliott said:
As long as we're trotting out aphorisms

The ones I quoted were from Python.
how about DRY: Don't Repeat Yourself. The rule couldn't be clearer:
don't repeat your SELF. ;) Yet that's exactly what explicitly
declaring self does, forces me to needlessly repeat what everyone
already knows: methods take the object instance as their first
parameter.

You've misunderstood "don't repeat yourself". It advocates *one*
definition of any given thing in the code. You are advocating *zero*
definitions of 'self' in the code.
 
B

Ben Finney

Bruno Desthuilliers said:
Ben Finney a écrit :

This one can be subject to discussion.

All the assertions in 'import this' are subject to discussion. They're
even contradictory.
Yeps, I think this is what I don't like here.


I'm not yet ready to vote for Edward's proposition - as you say, it
makes 'def statements into a class statement' a special case, and I
don't like special cases too much (OTOH, there actually *are*
special cases - __new__() being an example) - *but* it's not that
silly either IMHO, and I think this should not be dismissed on a
purely reactional basis.

My basis for rejecting the proposal is that it claims to offer net
simplicity, yet it breaks at least two of the admonishments that
simplify Python.
 
E

Edward Elliott

Ben said:
The ones I quoted were from Python.

Yes I know where it's from.
You've misunderstood "don't repeat yourself". It advocates *one*
definition of any given thing in the code. You are advocating *zero*
definitions of 'self' in the code.

It's implicitly defined by the language/runtime, so I shouldn't need to
define it in my code. Doing so is duplication of effort, aka DRY. An
implicit definition is not an empty definition. Where do the semantics of
'while' and 'for' come from? Same thing, it's implicit in the language.
 
E

Edward Elliott

Ben said:
My basis for rejecting the proposal is that it claims to offer net
simplicity, yet it breaks at least two of the admonishments that
simplify Python.

As do other features of Python. Or did you forget the follow-up to the
special cases "rule"?

Special cases aren't special enough to break the rules.
Although practicality beats purity.
 
E

Edward Elliott

Marc said:
Okay, let's start with writing a simple text processor for this little
mess::

I didn't even try to wade through that morass of monocharacter variables.
Anyone wanna summarize the point of that code?
 
B

Ben Finney

Edward Elliott said:
I didn't even try to wade through that morass of monocharacter
variables. Anyone wanna summarize the point of that code?

As I understand it, the point was not what the code does, but to give
a sample input (a Python program) for the "simple text processor" you
described to wade through.
 
E

Edward Elliott

Ben said:
As I understand it, the point was not what the code does, but to give
a sample input (a Python program) for the "simple text processor" you
described to wade through.

Ah, well then, there's no need for a full-blown parser. It should suffice
to recognize a class definition and modify the parameter list of every def
indented one level further than that. Then pick out the static methods and
'undo' those. Can be done in one pass by keeping the class definition in
memory until you've scanned the whole thing, then adding self where needed
as you spit it back out.

Implementation is left as an exercise for the reader. :)
 
B

Bruno Desthuilliers

Edward Elliott a écrit :
I don't see how nested functions change anything. If they're nested in a
method, they can access self, but the name mapping is done at runtime.
Unless you mean a nested fucntion which is dynamically added as a method,
but that's the same case as the next one.

Nope. I just wanted to point out that just checking for def statements
in the scope of a class statement is not enough to decide if it has to
be treated as a method.

(snip)
I agree, but it's good to keep options in mind.

regexp are not an option !-)
I have no doubt that's true for a lot of people. Hell I probably prefer the
current approach because 1) it's not a big deal in practice, and 2) I can
use the shorter 'me' or 's' in place of self in my own code, which I
couldn't do under the change

Now *this* would be a +1 !-)
(well, I could add 'me = self' as the first
statement of any method, but that's clumsy). My objections stem more from
an elegance standpoint. Of course elegance is in the eye of the beholder.

Indeed...
 
B

Bruno Desthuilliers

Marc 'BlackJack' Rintsch a écrit :
(snip)
Okay, let's start with writing a simple text processor for this little
mess::

def b(c):
def d(r, *s, **t):
print '***'
c(r, *s, **t)
return d
What a nice, readable, highly pythonic code...
(snip)
 
B

bruno at modulix

Ben said:
All the assertions in 'import this' are subject to discussion.

Of course - but that was not the point. I meant that having implicit
self in methods would not break this assertion much more than the
current strange mix of explicit declaration of self + implicit passing
of self.
They're
even contradictory.

That's the nature of Zen, isn't it ?-)

(snip)
My basis for rejecting the proposal is that it claims to offer net
simplicity, yet it breaks at least two of the admonishments that
simplify Python.

One could also claim that the current scheme *actually* breaks
explicit-implicit and special-case rules in that the instance is
implicitely passed at call time for the bound methods special case -
which is ok IMHO since practicallity-beats-purity. Also, FWIW, Edward's
proposition can be justified (at least that's Edward's POV) by the first
rule : beautiful is better than ugly !-)

disclaimer : None of this is to be taken as the expression of my own
position on this proposition...
 
B

bruno at modulix

Edward said:
Ah, well then, there's no need for a full-blown parser. It should suffice
to recognize a class definition and modify the parameter list of every def
indented one level further than that.

won't do :

class CounterExample(object):
if compute_some_const_according_to_phase_of_moon():
def meth(...):
do_something(self, 42)
else:
do_something_else(self)

Then pick out the static methods and
'undo' those.

don't forget classmethods...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top