The Artima Developer Community
Sponsored Link

Weblogs Forum
Where Did All the Beautiful Code Go?

97 replies on 7 pages. Most recent reply: Apr 14, 2006 9:55 PM by Andy Dent

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 97 replies on 7 pages [ « | 1 ... 4 5 6 7 ]
Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Where Did All the Beautiful Code Go? Posted: Apr 5, 2006 10:16 AM
Reply to this message Reply
Advertisement
"A human programmer may look at the code and say, "why, it's obvious that the method won't return null in the case in question."

And because Nice is designed to re-use existing Java libraries there will be many Java methods that return null or an Object.
So we can test for null before calling the method, or we can add an assertion to test for null at runtime, or the compiler will show an error.

?MyObject getSomething(boolean condition) {
return (condition)? new MyObject() : null;
}

void anotherMethod(MyObject m) {
println("received myObject");
}

void main(String[] args) {
var myObject = getSomething(true);
if (myObject != null) anotherMethod(myObject);
anotherMethod( notNull(myObject) );
anotherMethod(myObject); // line 13
}

class MyObject { }

>nicec --sourcepath .. -a t.jar test
nice.lang: parsing
test: parsing
test: typechecking

test.nice: line 13, column 4:
Arguments (?test.MyObject) do not fit:
nice.lang.void anotherMethod(test.MyObject m)
compilation failed with 1 error

That stupid compiler is preventing me from getting my work done!"
Wouldn't that same programmer complain that 'those stupid unit tests are preventing me from getting my work done'?

piglet

Posts: 63
Nickname: piglet
Registered: Dec, 2005

Re: Where Did All the Beautiful Code Go? Posted: Apr 5, 2006 12:02 PM
Reply to this message Reply
What is your point, Isaac?

Btw I am convinced of the benefits of static type checking, and I don't give much credence to the dynamic crowd's claim that static checking is too restrictive and unchecked code with unit tests is just as stable. The question I'm asking is is how far static checking can go before it becomes really restrictive, and what can realistically be achieved by pushing them further.

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: Where Did All the Beautiful Code Go? Posted: Apr 6, 2006 4:12 AM
Reply to this message Reply

Take as a simple example an index bound check. The index will be the result of some computation, so in order to prevent out of bound errors, you would have to prove that the computation in question cannot, under any circumstances, yield a wrong result


Actually, the proposed approach goes the other way around: it does not have to make sure that the computation does not return an invalid array index value, but that the returned value is correct for using as an array index.


Assume that some caller calls getSomething() and passes the result to another method, which has the specification that the input may not be null. The compiler probably can't foresee how the condition will evaluate, so in order to enforce the requirement, it would have to reject this code.
However, the code may be correct. A human programmer may look at the code and say, "why, it's obvious that the method won't return null in the case in question. That stupid compiler is preventing me from getting my work done!"


The approach I proposed actually does the same thing humans do; I actually derived it from observing how me and other programmers realize if a piece of code will actually evaluate to some value. It may sound strange at first, but take a few moments to consider how a human decides that "the method won't return null in this case": what we do is to examine the source code, derive the possible outputs, then compare them with the possible inputs. We do not actually run the algorithm in our heads, but we put all the possible values in sets.

So, in your example, most probably the tool will be able to understand the same thing that a person does, and thus not reject the code.


In fact, some programmers prefer dynamic languages for that very reason, they feel that static checks are too restrictive. A language which pushed compile-time checks even further, along the lines you suggest, would hardly become very popular.


I agree with you. In cases that a programmer wants to simply start coding and discover the errors later, this approach is restrictive. There is not one shoe to fit every foot. But in cases that programming is done at professional level involving thousand dollar contracts (and more), maybe this approach is better.

There is an interesting discussion in Slashot this morning about Eiffel and some people said that they hate contracts.


This isn't in itself a reason to dismiss the concept but the point is you have to make a credible case not only that it is possible, but also that it is worthwile.


Of course. I am not even convinced myself yet. That is why we are discussing this.


No static verification, indeed no methodology in the world, can guarantee correctness, so the question is how to get the best result with respect to the ressources available.


Indeed. The only think you can prove is the absence of errors for the constraints you have set. But it is not possible to prove that the constraints you have set are the correct ones.


Btw I am convinced of the benefits of static type checking, and I don't give much credence to the dynamic crowd's claim that static checking is too restrictive and unchecked code with unit tests is just as stable. The question I'm asking is is how far static checking can go before it becomes really restrictive, and what can realistically be achieved by pushing them further.


I would like to point out, in the context of this Nice example, that the approach presented above maintains the truthfullness of a statement across code (if there is one, of course). This means that once you check that a pointer is not null, then you do not have to check that again. This is not the same as in Nice, where every possible pointer access that is not of type ? must be checked for not being null. It also means that you do not have to have a separate non-nullable pointer type. Here is the analysis of your example:


//input: condition:{true or false}
//output: {null or MyObject}
MyObject getSomething(boolean condition) {
return (condition)? new MyObject() : null;
}

//input: m:{myObject}
void anotherMethod(MyObject m) {
println("received myObject");
}

void main(String[] args) {
//(1)
//input: true -> condition: {true, false} OK
//output: {null, MyObject}
var myObject = getSomething(true);

if (myObject == null) {
//(2)
//myObject is null.
//myObject:{null, MyObject} => myObject:{null}
//input: myObject:{null} -> myObject:{null} OK
System.out.println("error: null MyObject");
return;
}

//(3)
//myObject is no longer null.
//myObject:{null, MyObject} => myObject:{MyObject}

//(4)
//input: myObject:{MyObject} -> m:{MyObject} OK
anotherMethod(myObject);

//here rest of the code supposes that myObject is not null
}


At point (1), the object MyObject is created. The result may be null. We check that the input value to getSomething is a subset of the parameter condition.

At point (2), the block if (myObject == null)... has as input a myObject variable that is null. This is also ok, as myObject can be null. We check that the input value (myObject:{null}) is a subset of the required value (myObject:{null}). The static if part assures us about that.

At point (3), we see that myObject can not be null any more, because the branch with myObject == null does not reach this point. Therefore, the set of possible values does no longer have null as its input.

From point (4) and below, the compiler assumes that myObject is not null, and thus happily accepts the code that uses the variable.

So it seems that static verification that is not restrictive and thus frustrating can exist to a certain degree.

Of course the real question is if beautiful code can exist without static verification. I have no answer for that.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Where Did All the Beautiful Code Go? Posted: Apr 6, 2006 5:48 AM
Reply to this message Reply
> I would like to point out, in the context of this Nice
> example, that the approach presented above maintains the
> truthfullness of a statement across code (if there is one,
> of course). This means that once you check that a pointer
> is not null, then you do not have to check that again.
> This is not the same as in Nice, where every possible
> pointer access that is not of type ? must be
> checked for not being null.

That is not correct, and more positively Nice provides a limited example of the functionality you are describing:
?MyObject getSomething(boolean condition) {
return (condition)? new MyObject() : null;
}

void anotherMethod(MyObject m) {
println("received myObject");
}

void main(String[] args) {
var myObject = getSomething(true);
if (myObject == null){
println("error null myObject");
return;
}
anotherMethod(myObject);
}

class MyObject { }

$ /opt/nice-0.9.10/bin/nicec --sourcepath .. -a t.jar test
nice.lang: parsing
test: parsing
test: typechecking
test: generating code
test: linking
test: writing in archive
nice.lang: writing in archive
$ /opt/jdk1.5.0_05/bin/java -server -jar t.jar
received myObject

piglet

Posts: 63
Nickname: piglet
Registered: Dec, 2005

Re: Where Did All the Beautiful Code Go? Posted: Apr 6, 2006 7:33 AM
Reply to this message Reply
The approach I proposed actually does the same thing humans do; I actually derived it from observing how me and other programmers realize if a piece of code will actually evaluate to some value. It may sound strange at first, but take a few moments to consider how a human decides that "the method won't return null in this case": what we do is to examine the source code, derive the possible outputs, then compare them with the possible inputs. We do not actually run the algorithm in our heads, but we put all the possible values in sets.

My example was designed to show that you have to be able to predict the runtime behavior in order to predict the output. If you just analyze the set of all *possible* outputs (like type inference systems do), your checking mechanism will often have to be restrictive.

So, in your example, most probably the tool will be able to understand the same thing that a person does, and thus not reject the code.

If you think you can describe an algorithm that would achieve this then I suggest you elaborate your ideas and submit them to an academic journal.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Where Did All the Beautiful Code Go? Posted: Apr 6, 2006 11:14 AM
Reply to this message Reply
What is your point, Isaac?
In a previous post (Apr 5, 2006 11:44 AM) you wrote 'However, the code may be correct. A human programmer may look at the code and say, "why, it's obvious that the method won't return null in the case in question. That stupid compiler is preventing me from getting my work done!"'.

Textbook stuff: "...a type system for a general-purpose language must always either over- or under-approximate: either it must reject programs that might have run without an error, or it must accept programs that will error when executed." p239 Programming Languages: Application and Interpretation

So yes the code may be correct, and still be rejected by a type checker; and yes the specific type system for language X may be riddled with inconsistencies that make it a PITA.

However, the fact that a programmer thinks the method won't return null is a long way from making it a fact that the method won't return null. We get it wrong a lot. We should rail against badly designed type systems and we should obsess about catching our mistakes.

In Nice isolating where null pointer exceptions can occur is quite straightforward.

Bruce Eckel

Posts: 875
Nickname: beckel
Registered: Jun, 2003

Re: Where Did All the Beautiful Code Go? Posted: Apr 6, 2006 12:01 PM
Reply to this message Reply
> The
> question I'm asking is is how far static checking can go
> before it becomes really restrictive, and what can
> realistically be achieved by pushing them further.

This is where the discussion gets interesting. The boring discussion is "static/dynamic type checking is good/bad." The interesting one is "here's a device that verifies correctness, here's what it gets you, and here's how much it costs."

I think the discussions usually break down at the point where we start trying to define costs and benefits, primarily because costs and benefits vary from one situation to the next. For a company that hires a particular type of programmer and produces a particular type of product, the static type checking device (for example) costs more or less than it does in another company under a different situation.

Andy Dent

Posts: 165
Nickname: andydent
Registered: Nov, 2005

Re: Where Did All the Beautiful Code Go? Posted: Apr 14, 2006 9:55 PM
Reply to this message Reply
Bill Venners:
> Now, it is up to the management to decide how to balance
> long and short term goals, and if they decide that short
> term is more important, I wouldn't second guess them. So
> long as they understand the tradeoffs of accumulating
> debt, they can make an informed decision.

An important professional responsibility of the developers at this point is to not let management make such deferral of cost decisions without it being accompanied by formal reports in the issue management system.

This may require a bit of coaching and careful monitoring by the team lead - the idea is not to let grievances over decisions spill into spiteful logging.

It is also an important defensive strategy for the team, especially when the decision making has no other written trail.

Most software processes fail to capture the discarded alternatives at minor and major decision points.

Flat View: This topic has 97 replies on 7 pages [ « | 4  5  6  7 ]
Topic: Shuttleworth Foundation Workshop on Analytical Skills Development Previous Topic   Next Topic Topic: Software Architecture is Leadership

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use