monkey2 icon indicating copy to clipboard operation
monkey2 copied to clipboard

Disallow Function() in Interfaces

Open Difference opened this issue 7 years ago • 3 comments

Monkey2 should/could disallow Function in interfaces, because it is unclear what it does.

"it's kind of pointless putting a function in an interface - an interface is a bunch of absrtract methods. A function is NOT an abstract method! So the interface name could be used to 'scope' a plain old function, and that's about it."

Difference avatar May 17 '18 07:05 Difference

Declaring a Function in an Interface is arguably useful : it forces the Function to be defined in any Classes that implement the Interface. Isn't that what an Interface is for at a conceptual level? To define an common set of Methods/Properties/Functions/Fields whose use is then enforced on Classes that implement the Interface? Just because it is done one way by C++/Java etc. doesn't mean that theirs is the best way!

Monkey currently also allows Functions to be labeled Abstract or Virtual within Class definitions. This is basically the same issue and should/could also be disallowed. However, my above argument still holds - an Abstract Function delcaration forces it to be defined in any derived Classes. This has useful applcations. On the other hand, it is harder to argue the case for a Virtual Function (and while they are theoretically possible, I see no useful application for them as they lack polymorphism).

Currently, using a Function in an Interface, or labeling a Function as Abstract or Virtual generally leads to the compiler crashing unpleasantly as soon as that Function is invoked unless you are very careful. This is clearly not good.

In any case, the docs don't explain any of this and the current implementation is unclear. Something ought to be changed to improve the current situation... but disallowing Functions in Interfaces (or as Abstract declarations) could potentially break existing code and does remove some functionality that is potentially useful.

Is there a better option?

arpie42 avatar May 17 '18 14:05 arpie42

I don't agree that interfaces should be able to define static level anything unless all features of a class are available to an interface.

I'm not exactly sure what Monkey2 treats Functions as. To my basic understanding, I think Monkey2 Functions are usable as [Static & Instance]-Level members. The biggest difference between a Method and Function though is that Functions don't have access to instance-level fields.

So, having Functions abstract between classes makes sense because the Functions defined on a class level understand and have access to all scopes of any instance passed. Functions at a class level also have access to the static levels of the class it was defined in. The reason we can use Functions via instances is allowable is because the compiler can make decisions on which Function to invoke based on the Class being used to store the instance; it doesn't use the instance type. I suspect there would be errors if a Class variable which you stored an inherited instance into, had an undefined Function(abstract or virtual), there would be errors and then it would be considered invalid code. Therefore, because you don't actually define any of the fields, methods, etc, inside of an Interface it just wouldn't ever make sense.

In my opinion, an interface should describe how instances work and not how classes work - at the compiler level.

XANOZOID avatar May 17 '18 22:05 XANOZOID

It looks like I'm in the minority for arguing to allow Function declarations in Interfaces (and in Abstract Classes too). This has come up before on the Monkey forums and I failed to convince anybody there, either :). In any case the current implementation is flawed - it is easy to cause a compiler crash by calling an Abstract Function which lacks a definition. The parser doesn't currently issue any sort of warning if you declare a Function in an Interfaces, nor for labelling them as Abstract or Virtual. The docs don't elaborate on how to use Functions at all. This situation is obviously not ideal. But this is a minor niggle in an otherwise delightful language. I would personally like to see an implementation where Interfaces can be used to declare a Class interface in its entirety, including Functions. This is the broadest possible implementation, adds potentially useful funcionality, but is probably also the hardest for Mark to implement! If you limit an Interface to just declaring how an Instance works, then you limit its use to just that. If an Interface can declare how an entire Class should work then it can be used for both (ie. you can declare an entire Class, Functions and all; or you can choose just to declare the Methods and hence just how the instance will work). Everybody would be happy :)

arpie42 avatar May 18 '18 20:05 arpie42