-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Defining instance methods (with defaults) of their super class doesn't work #389
Comments
So, in my opinion, the second case is the worse one. In principle, the compiler did the "right thing" by not allowing the already established != to get overwritten. Of course there must be an error message in such a case. First, I think it is immaterial, whether the method is a default class method or not, since when you make an instance of a class with default methods and don't give an implementation, then the code is simply copied from the class definition. Later, there is no way to know whether this implementation was supplied by the user or not. In the following, I'll draw up an argument why overriding an already implemented function of the superclass should be forbidden. Consider a type T and 3 modules E, O and M. Now consider a function Worse, in modules O and M, when we use (!=), we don't really know, nor have any influence, which (!=) would be used. The point is that the type checker collects the constraints raised, such that
would get
would get Conclusion: An instance for For example:
must not override (==) and (!=). And I guess here is the reason why there is no error message. Because a Hence, the following is possible, and should be possible henceforth:
And clearly, when we define a differing (!=) this should be respected:
And finally, an all-in-one instance definition (e.g. By the way, the repl session above also shows nicely that the instance definitions are processed in dependency order, not in the order they appear in the source file. Perhaps, to achieve what we want (ignore synthetic mehods if there is already an implementation, but complain about user defined ones) we would need a flag in the SymI (or whatever it is now) that tells whether this is a derived instance, and based on that, the error is emitted or not. It should be so as if the It goes without saying that this would also make the compiler crashing program illegal, so that the compiler would fail well before it even reaches the type checking pass (which is where it crashes). |
Adding as a memo: If both If at least
|
Spawned from #387
For example,
Eq.!=
has a default implementation. If aninstance Ord
(subclass ofEq
) has an implementation of!=
, it fails. How it "fails" differs by which module an instance is defined in.Be prepared because there are a lot of example code below.
(used a3c4f77, the current
master
).Examples
If an instance is defined in the same module as the data type
If an instance is defined in the same module as the data type, the compiler crashes.
Foo.fr
:Main.fr
:Compiling:
The interesting point is that the compiler crashes at
Main.fr
but not atFoo.fr
.If an instance is defined in the same module as the class
If an instance is defined in the same module as the class, the compiler silently ignores the method definition and the default implementation is used.
The following example makes up two classes
MyEq
andMyOrd
which mimicEq
andOrd
respectively.Foo.fr
:MyEq.fr
:MyOrd.fr
:Foo.fr
:Compiling and running this program outputs
true
. However, it's likely that the programmer expected it to crash (at runtime) by evaluatingerror
.If an instance is defined as an orphan
By replacing
instance MyEq
andMyOrd
byEq
andOrd
resp. in the above example, we have orphan instances. The result is the same; compilation successful, running it outputstrue
.Discussion
Implementing methods which have default implementations from the super class should be explicitly forbidden. The compiler should always emit a not-a-crash error on compiling a module which includes offending instances.
The text was updated successfully, but these errors were encountered: