gracelang / language

Design of the Grace language and its libraries
GNU General Public License v2.0
6 stars 1 forks source link

When should we detect structural errors in a program? #59

Closed kjx closed 8 years ago

kjx commented 8 years ago

Ideally, trait composition errors should be detected as soon as possible (aka "statically"). But do we want to be able to run those programs anyway and see where they crash (as with type "errors')? Which checks should be in the core language (which prevent code running) and which checks in dialects (which can be ignored)?

At #32, andrew wrote:

Personally, because I want to be able to use Grace for experimental as well as production coding, I would like abstract methods to remain optional. It would be fine for a dialect to prevent the instantiation of a class that contains an abstract method, but not for the base language.

I propose other trait conflict errors etc should be in the same category as #32 abstract, and #1 case

apblack commented 8 years ago

Although it may seem strange, I would like those composition errors to be given statically.

Even Smalltalk detects some errors statically. For example, you can't have a cycle in th inheritance chain, and a subclass and its superclass can't use the same instance variable name. Why? because a program with such errors doesn't make sense.

Right now, a Grace object that has two wombat(_) methods is illegal. We could run it, and take the last one (or the first one, or choose randomly). We could even compile a third wombat(_) method that warns about the other two, and only execute it if it is invoked. But we don't: we warn the programmer that they have made a silly mistake.

A trait conflict is no different from these errors. We have jumped through all sorts of hoops to enable this error to be detected statically. So let's do it!

kjx commented 8 years ago

A trait conflict is no different from these errors. We have jumped through all sorts of hoops to enable this error to be detected statically. So let's do it!

so then we'll have to define what trait conflict error is and what it isn't. Is calling an abstract method a "trait conflict error"? Why one and why the other?

Again: the issue here is (conceptually) what's in the core language and what is in the dialect. I don't know how your latest stuff works, but for a while minigrace and Kernan both supported a more an object model that worked even when things weren't "manifest". Do we want to rule those out now?

KimBruce commented 8 years ago

If a construction introduces an error that cannot be fixed, then it should be declared erroneous at that point. An abstract method is something that can be filled in (fixed) later, so can be treated differently/ more leniently in some dialects. One of the issues of letting errors persist is that we have to provide semantics for them. If we rule them out as erroneous then we are freed from that.

kjx commented 8 years ago

in the compiler

kjx commented 8 years ago

so according to the protocol I wrote last week, this shouldn't be closed, but should be moved from "now" to "resolved, to be specd". which I've now done. sorry.

apblack commented 8 years ago

During our discussion, I asked repeatedly what kjx meant by "Nixonian". The response was that this was my (apblack's) term, which completely confused me.

In the shower this morning it occurred to me that kjx might have been referring to my ideas about the Wilson, Bush and Murrow treatment of errors, which are described in my paper "Object-oriented programming: Some history, and challenges for the next fifty years", or in the slides (see slides 59 and 60) from the original talk.

I still don't know what "Nixonian" refers to.

kjx commented 8 years ago

Andrew you're right - yes, this was what I meant to refer to - I was confusing your GW Bush for Nixon.
So, please interpret my references to "Nixon" as if to "Bush". This was in one of the earliest Grace slides too.

(I guess Nixon would be actually worse than Bush - the runtime would lie about what your program was doing - but it would protect the environment)

kjx commented 8 years ago

Under the Bush interpretation, all checks will be performed at runtime.

Grace Scotland Talk Extract.key.pdf

apblack commented 8 years ago

On 24 Feb 2016, at 12:33 , kjx notifications@github.com wrote:

Under the Bush interpretation, all checks will be performed at runtime.

Grace Scotland Talk Extract.key.pdf

And your point is ... ?

If you look at the slides that I referenced, you will see that they say "I'm for Morrow" — best-effort compile-time checks, plus runtime checks for everything else.

kjx commented 8 years ago

I honestly don't know what you're for. We agreed yesterday (I think) that "structural checks that cannot be fixed" would be prevented by the design, but other kinds of errors would proceed to runtime checks. I still don't really know how to tell which error is in which category.

Also: (using your terminology) Kim was for "Wilson" I think; the question is not just what you're for, but which other approaches are permissible. The slides you posted also says things like:

counter-example is more useful than a type-error message

under Bush, not Morrow.

apblack commented 8 years ago

When I said "a counter-example is more useful than an error message", I was thinking of type errors. Moreover, I was probably being too all-inclusive: a counter-example can often be more useful than a type error message, but it does depend on the message and when it's provided.

Suppose I write a class and declare that it is supposed to answer an object or type Wombat. A type error message that says "returned object does not have type Wombat" is not very useful. In contrast, a runtime error that says NoSuchMethod when I request asList on a wombat tells me exactly what's missing — but only when I actually request asList, which, in the absence of adequate tests, may be never. In this case, I think that the best thing might to give a warning in the IDE that the class is missing the asList method — pinpointing the error at the place where it occurs — but not to stop the programmer from running the code, because the programmer might well know that the asList method is missing, along with 20 others, but right now is working on getting the == method to pass the test suite, and will get to asList and the other missing methods in due time.

In the case of a trait composition expression, I think that the best thing is for the IDE to guide programmers to construct correct expressions by telling them what required methods are missing, what methods conflict, and so on. I think this because I actually used such a tool (the Traits Browser) for a couple of years. Then the Pharo people took it away, and I tried to program with traits without it — getting only runtime errors. Life got a lot harder.

In the case of Grace, the fact is that right now we don't have an IDE that's worth the name. We do have compiler that implements checks, though. To get a runtime error for a trait conflict, we must first detect it at compile time, and then generate a method that will raise the error at runtime. This is more work than just raising the error at the place where we detect it. This is exactly the opposite of the situation with type errors, where if we do nothing the NoSuchMethod errors will happen at runtime because of the way that objects work, and detecting them ahead of time is a lot more work (as well as being undecidable in the general case).

Hence, I propose that trait conflict errors be detected early. If it turns out that this is a problem for incremental programming, then we can change our minds, and do the work to postpone them.

kjx commented 8 years ago

I'm sure detecting early is useful, and am also quite happy to believe that it makes the most sense to implement inside minigrace.

I'm trying to take a more abstract view, I guess: I don't see why this particularly issue must be caught early, while many similar ones are not. Of course I'm inconsistent myself: things like syntax errors, exclude or alises clauses talking about non existing methods etc, I agree should be done early.

But the rest of the method-level inheritance errors aren't (apparently) to be caught early - and the "GW Bush" behaviour is what I understood we agreed on in Pomona...