1

I am working on a new class based, dynamically typed programming language where functions are first class objects. Functions defined inside a class (aka methods) are called passing self as first parameter while globally defined functions does not need to have the self parameter.

In a code like:

func foo(a) {
    return a*2;
}

class c3 {
    var p1 = 555;
    func init() {
        p1 = foo;
    }
}

class c2 {
    var p1 = 333;
    func init() {
        p1 = c3();
    }
}

class c1 {
    var p1 = 111;
    func init() {
        p1 = c2();
    }
}

func main() {
    return c1().p1.p1.p1(1234);
}

How can the compiler decide if self needs to be passed as first argument to p1(1234) or not? In this case p1 points to foo which is a global function that would not need the self parameter.

Marco
  • 783
  • 5
  • 21

2 Answers2

0

In Python, this is handled at runtime by the descriptor protocol.

Java handles this by not allowing objects to be called with (). Everything is called with method syntax, and the compiler knows whether it is a static or virtual method. The Java equivalent of function objects requires you to call a specific method on the object (foo.call() instead of foo())

I believe C++ handles this through the type system. If the name is a method, it's a method call. If it is a static method, it is a static method call. Otherwise, you're accessing the () operator on a field.

Antimony
  • 37,781
  • 10
  • 100
  • 107
  • Well, it’s not the method syntax alone that determines the type of invocation in Java. If you have an expression like `a.b.c(1234)`, `c(1234)` could be an invocation of a `static` method declared in a type `a.b` or an instance method invoked on the object found in the field `b` which could be a `static` field of the type `a` or an instance field of the object found in the variable `a`. The key point is the static type system allowing to look up the variables, types and methods at compile time and make a decision. – Holger Jun 15 '16 at 18:04
  • @Holger I tried to get at that by saying "the compiler knows whether it is a static or virtual method", but I guess I wasn't explicit enough. Also, https://gist.github.com/Storyyeller/fd97cccc02287dd40e43 – Antimony Jun 15 '16 at 19:10
0

Simple: c3.p1 is a member variable, not a method of c3. So when you call c3.p1 it simply doesn't get a self pointing to any instances of c3.

You might want to support bound methods, though:

class c3 {
    var p1 = 555;
    func bar() { print "Hello, world"; }
    func init() {
        p1 = self.bar; // NOT self.bar()
    }
}

In this case, the compiler still wouldn't pass a c3 self reference to c3.p1() but that's not necessary at the call site since self was already bound when self.bar was assigned to p1.

MSalters
  • 173,980
  • 10
  • 155
  • 350