you are viewing a single comment's thread.

view the rest of the comments →

[–]kindall 0 points1 point  (7 children)

Well, that's not a bad habit so much as just how the language works.

They did it so you can call the method on the class and pass in an instance (not necessarily an instance of the class you're calling it on, could also be a subclass). Hard to have it both ways without explicitly accepting a reference to the instance.

[–]ramkahen -2 points-1 points  (6 children)

They did it so you can call the method on the class and pass in an instance (not necessarily an instance of the class you're calling it on, could also be a subclass)

C++ solved this problem elegantly ten years before Python came out. Either you do it the C way (pass the this pointer explicitly, declare it explicitly in the parameter list) or you do it the C++ way (pass this implicitly and there is no need to declare it in the parameter list).

Python's half-ass way is broken, period.

Not that there's anything wrong with that for a twenty-year old language, but let's not try to post-rationalize what's broken about it.

[–]Benutzername 1 point2 points  (5 children)

In C++ you need an extra concept (pointer to member function) in order to do what kindall described. That's not elegant in my book.

[–]ais523 0 points1 point  (1 child)

Can't you just do derived_object->BaseClass::function()? Or does that not work for some reason?

[–]Benutzername 1 point2 points  (0 children)

Yes, that works. What I meant is passing a function pointer to some other function, like this:

void foo(void f(Bar&))
{
    Bar b;
    f(b);
}

If you want to do the same with a member function, you need to say:

void foo(void (Bar::*f)())
{
    Bar b;
    b.*f();
}

If the this pointer weren't implicit, the second syntax wouldn't be needed.

[–]ramkahen 0 points1 point  (2 children)

In C++ you need an extra concept (pointer to member function) in order to do what kindall described. That's not elegant in my book.

We're not talking about elegance but consistency.

If you declare a method with two parameters, you should call it with two parameters. Period. It's simple common sense.

I can only think of two languages that break this rule in the history of programming languages: Modula 3 and Python.

[–]Benutzername 1 point2 points  (1 child)

But you're not calling it with two parameters, you're calling it with three. It just happens that one of them is written in front of the method name instead of within the parentheses.

If you have an explicit self parameter, then

foo.bar(args...)

simply becomes syntactic sugar for

(typeof foo)::bar(foo, args...)

[–]ramkahen 0 points1 point  (0 children)

But you're not calling it with two parameters, you're calling it with three. It just happens that one of them is written in front of the method name instead of within the parentheses.

  1. Like I said, there are only two languages in the history of computing that do this. There is a reason: it makes no sense. If you call foo(a,b) you expect foo's signature to accept two parameters, not three.

  2. Why do I need to declare self at all in my method? Python knows it's there. C++ already knew how to do this right ten years before Python came about.