Tags

My wishlist for (200|JDK)7

December 23rd, 2006

Combined Types

I’d like to declare a method that requires an Object implementing more than one interface, just a shorthand for
interface MyMethodsRequiredParameter extends Intf1,Intf2 {};

foo(MyMethodsRequiredParameter bar);

This can be done with generics (kudos to Ricky! ):
<MyMethodsRequiredParameter extends Intf1 & Intf2>foo(MyMethodsRequiredParameter bar);

Well, a bit shorter syntax would be nice:

foo(Intf1&Intf2 bar);

The reversed problem is the creation, it can be done via java.lang.reflect.Proxy but it is tedious, so why not

Intf1&Intf2 myMethodsRequiredParameter = new Object() implements Intf1,Intf2 {…};

Limiting Interfaces & Views
When integrating third-party code you just simply don’t want to take all of it, so you wrap it to expose on that part of the interfaces you need. So I want to say

view MyList as java.util.Collection{
int size() = java.util.Collection.size();
}

To use just one method from Collection. The effect was as if Collection would implement
interface MyList {
int size();
}

The problem with a stand-alone interface is that size() there is not the same (java.lang.reflect.)Method and so I have to wrap the whole API by delegation

class StupidList implements MyList {
final private Collection coll = new ArrayList();
public int size() { return coll.size() }
}

And I do not only have to wrap the types, also write façades for the whole API because MyList is not a Collection… you get the point: Hundreds or thousands of line of stupid code that do virtually nothing.

More advanced

view Iterator as java.util.Enumeration {
bool hasNext() = java.util.Enumeration.hasNextElement();
Object next() = java.util.Enumeration.nextElement();
}

or

view StupidList implements MyList as ArrayList {
public int size() = ArrayList.size();
}

The important difference to the delegation is that StupidList stays an ArrayList it is only that the type ArrayList is hidden. Views need to co-exist:

view StupidList implements MyList as HashMap {
public int size() = Map.size();
}

So both types HashMap and ArrayList use a common “interface”, the only restriction is that views (nor their subclasses) can never be instanciated.

Another very useful application of views is implicit conversion

view Integer as Double{
Integer(){
if (doubleValue()>Integer.MAX) throw new IllegalArgumentException();
if (doubleValue()
}
double doubleValue()=Double.doubleValue();
int intValue() = Math.round(doubleValue());
}
This view does two things at once: It checks if the value is OK for an int and redefines the conversion. With this view this code

foo(Double dd) {
Integer ii = d;

is equivalent to

foo(Double dd) {
if (dd.doubleValue()>Integer.MAX) throw new IllegalArgumentException();

if(dd.doubleValue()
Integer ii = Integer.valueOf(Math.round(dd.doubleValue());

In fact not entirely. With the view ii stays a Double that just looks like an Integer. This is more important for mutable objects where the original object gets manipulated via the interface of another type! Views are also a better cast method, as they are not casting but dynamically inject the requested interface.

Perhaps views are also an alternative to type inference. Imagine I could simply say
boolean notEmpty(T[] someArray)
MyList list = Collections.asList(someArray);
return list.size()>0;
}

The declaration is not so difficult and barely redundant. I declare a MyList because this is what I need. The view logic wraps the concrete type I will receive so I don’t have to figure out what will be the type return from the expresion on the right.

Technical issues
The view idea had been borrowed from Scala. There the conversions are controlled by implicit parameter that are visible in the scope of the invocation. I am not sure if this would be the right idea for Java. Where should we put a declaration for the view Integer. The Java convention is to place a top-level object in a file of the same name. Java.lang.Integer is already taken and injecting such a powerful feature outside the package will compromise security. Super-packages (JSR 294) might help to solve this problem as view will be the killer application for the superpackages.

Methods as first-class objects

This is an extension to the closure proposal that seems to be sure to come for JDK 7

class Mine {
public void doit() {

}
}

foo(Mine mine) {
call({=>mine.doit()});
}
call({Mine.doit()} func) {
func();
}

This is very close to Closures. Closures are indeed a way of implementing it:

call({=>Void} func);

would work fine but would accept any void function with no parameters. On the other hand declaration referencing a concrete method is of limited use as it could be replaced by

callDoit(mine)

as the method is fully fixed; on the other hand this exposes the entire object, also calling static methods simply does not work that way. The real power of methods being first-class is meta programming:

class CanDo {
CanDo({Mine.doit()} func) {
{this.doit()} = func;
{this.doThat()} = func;
}
abstract final void doit(); //abstract final-> ctor provides implementation
volatile void doThat() {}; //volatile method: implementation can be changed
}

with closures:

class CanDo {
private final
{=>Void} thisFunc;
private
{=>Void} thatFunc = {=>null};

CanDo({=>Void} func) {
thisFunc = func;
thatFunc = func;
}
final void doit(){thisFunc()};
void doThat() {thatFunc()};
}

Closures are a bit more verbose and we cannot declare “the quality” of the method (e.g. which interface declared it).
More from Closures

Any method should be allowed to declared its return type to be Unreachable, this allows to write “exit methods”:

class Foo {
Unreachable throwException() throws RuntimeException {
RuntimeException re;
// form here a nice exeption object
throw re;
}

int bar1() {
throwException(); //Today an error!
}
}

Gemüse! Auflauf!

December 17th, 2006

Man nehme:DSC01715

  • 1 Aubergine
  • 1 Zucchini
  • 4 Tomaten
  • 4 Kartoffeln
  • 2 Grüne Pepperonischoten
  • 1 Stange Porree
  • 500ml Gemüsebrühe
  • Olivenöl
  • 100g Speckstreifen (Allumette)
  • 70g geriebenen Emmenthaler
  • Pfeffer, Salz, Oregano

Die Kartoffeln schälen und in etwa einen halben Zentimeter dicke Scheiben schneiden und in der Gemüsebrühe halb gar kochen.

In der Zwischenzeit die Aubergine ebenfalls in Scheiben schneiden (selbe Größe wie die Kartoffeln), die Zucchninis und Tomaten etwas dünner, die Peperonis (sollten nicht zu scharf sein) nochmals feiner. Alles in eine Auflaufform geben.
Speckstreifen nach Geschmack andünsten.

Die Kartoffeln abgiessen und zu den restlichen Zutaten geben. Mit Olivenöl benetzen und mit Pfeffer uns Salz würzen, dabei vorsichtig durchheben.

Käse darüber streuen und schliesslich die Speckstreifen obenauf.

Bei mittlerer Hitze ca. 30 Minuten im Ofen - fertig.

Dazu: Cotês du Rousillion 2004

JavaScript (doesn’t) sucks … but it can get horrible

December 15th, 2006

Just look here and then there. As I read the first, I knew from the headline that there will be the second.

First of all JavaScript is a powerful language, if you still think it is a small language to animate some icons, look what Douglas Crockford has to say on it (http://javascript.crockford.com/javascript.html); even if you are a hardcore programmer you’ll have to admitt that it is damned powerful.

What it makes it also important is that that it is ubiquitous. All browser implement it out of the box and there are less security concerns than with any other language on the browser platform.

But it is also a horrible language. One half of the story is the platform. There isn’t just browser, there are at least four (IE,Mozilla,Opera,Safari). They are similar, but far from being equal. They remind me of the subtle difference between various UNIXes I dealt with 10 years ago (we had to support  8 UNIX and all “tar” commands behaved differently). The browser is the OS for the web-clients (I say clients here, on the server side it is not better if not even worse). For any mid-scale use (=your are neither Google nor your programming your homepage) you have to use some toolkit to harness  the power of JavaScript and DHTML. Java main strength is that the platform is virtually no problem, modern C++ use relies on libraries (toolkits in newspeak) to achieve the same.
This is part of the reason why there are so many libraries and generators like (GWT and ZK). The other part is managability of the code; it boils down to the same battle as between Java and Ruby. As JavaScript is (ironically) as expressive as Ruby, it shares the same problems. Both language allow to make marvelous thing with little code, but the problem to manage several 100kloc* written by large, distributed teams over years is either not proven to be solvable (in case of Ruby) or proven to be unsolvable (in case of JavaScript). This is for sure too general, but for average-quality projects not too far off.

I am not talking about Ruby here (a well-designed language BTW), but JavaScript has some serious issues:

  • There are some flaws in the spec (what is “this”)
  • encapsulation asks for a horrible syntax
  • versioning on the “deployment”
  • IDE-support is poor, thus
    • limited refactoring
    • debugging

This limits productivity as soon as the complexity grows beyond a small team. This means that it is well possible to have high-quality toolkits or to use (like GWT) JavaScript like advanced bytecode, but projects like Phobos can get you into trouble even if you start off well. If you know you will perhaps never reach the complexity where the know issue become a problem - and I think 80% of all projects never do - the issues are managable or non-existant. For the other 20% (large enterprise applications) that pay 80% of the salaries,  I find it too risky or frankly - from 1st-hand experience - “inappropiate”.

*On complexity: If a language promises that you can do something with a tenth of the code you’d need in language X; this might be right. But don’t expect that this resolves your complextity problems. Most problems complexity is not linear like the code reduction you might get (let’s leave out the inherent complexity); it is quadratic or exponential at worst. A better (=more appropiate for your problem) language will only buy you (at best) some time. You have to work on the problem to survive in the long run and you have to use tools, so a well “toolable” language (and Java is perhaps best in this category, at least in respect of existing tools, for example Jackpot) can easily overcompensate a bit verbosity.

Beyond Java [was: The Enhanced For-Loop]

December 8th, 2006

I have to say that I find the enhanced for loop useful as a chocolate teapot. I cannot count how often I refactored an iteration into a for just to redo it afterwards. Some times you want to delete via calling remove on the Iterator, sometimes you need an index, well it quickly gets ugly.

Triggered by http://kawagner.blogspot.com/2006/08/java-enhancements-i-would-like-to-see.html and learning C# I started playing with the idea to wrap Iterable to provide access to an index, remove and filtering (plus paired iteration). Well it became ugly. Java and the generics are bitchy sometimes, have a look at it, maybe you find it useful (I find it insane:-)
enumerator.zip

I don’t think it is finished and I don’t think that I will finish it ever. The reason why I put this is out was just a side-kick in Javaposse #94 where the index issue was raised with the remark that someone might implement it someday - well I already did.

The point why I stopped working on it and I really developped an aversion against this code (now you have to have a look at it) was that I started with Scala; a really nice language that has enough FP to write expressive code, enough OO to fit into today’s development mainstream and integrates into .NET and Java so that existing code can be leveraged. It is statically typed (I had too much hassle with JavaScript that I could ever consider dynamically typed code in larger scale development) that makes it strict enough to have powerful type inference. Of course it has it rough edges and limitations, but it addresses the problems I find hard to tackle with Java reasonably well - there are problems that can be solved more elegantly with Ruby, but I think I still need some more practice with Scala before I give up on them.
PS: I think the index in a loop is not needed in a pure OO-design, but where do you ever find a pure OO design

The Anti-Agile Manifesto

December 8th, 2006
  1. Don’t show the customer the software before it is finished
  2. Develop all functions in parallel
  3. Presentations only on codebranches that are not in the dev stream
  4. Estimates have to be done upfront by people who are not involved in development
  5. Don’t specify user acceptance tests
  6. Code-reviews must focus on trivialties, so as indentation and variable prefixing
  7. Specify atomic operations only

Why:

  1. In case you misunderstood the customer or you want to do something the customer doesn’t want for sure; he will have no time to demand changes
  2. So all functions are developed at equal right; thing you didn’t understood well can be done in the crunch so that you don’t waste too much time on it
  3. The (core) developers can take so some time of to hack a demo while the others can crank out code without guidance
  4. Developers and architects might not give you estimates that fit into the project plan or budget, they have to deliver and not to complicate the planning
  5. The user has no idea what he wants and we cannot help him to find out, thus it is a waste of time
  6. Code style-guides fit any project and can be reused. If you feel unconfortable with it, add some unfulfillable criteria like “the code must handle all possible input data” or make your developers think: “demonstrate that the JavaScript is really needed”
  7. Developers are code monkeys, they won’t understand business values, so you have to tell them to write a 1 into column “X” when the user clicks a thing labelled “Delete”

Feel free to add more points in the comments…

I know understand why the agile manifesto had been created.