Tags

Closure puzzler or enum references considered harmful

February 7th, 2008

SPOILER - don’t read this if you want to figure out the Neapolitan Ice Cream Puzzler by yourself!

Neal Gafter posted a Closure Puzzler that hasn’t too much to do with closures, but shows that Static initializers considered harmful is not limited to the old enum-pattern, but also applies to Java 5 enums. Here the Java 5 version of his code for those who don’t get the closures code or simply are too lazy:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Compare {
	static <T, U> List<U> map(List<T> list, Transformer<T, U> transform) {
		List<U> result = new ArrayList<U>(list.size());
		for (T t : list) {
			result.add(transform.invoke(t));
		}
		return result;
	}

	public static void main(String[] args) {
	        List<Color> colors = map(Arrays.asList(Flavor.values()), new Transformer<Flavor,Color>(){public Color  invoke( Flavor f ){return f.color; }});
	        System.out.println(colors.equals(Arrays.asList(Color.values())));

	        List<Flavor> flavors = map(Arrays.asList(Color.values()), new Transformer<Color,Flavor>(){public Flavor invoke(Color c){return c.flavor;} });
	        System.out.println(flavors.equals(Arrays.asList(Flavor.values())));
	    }
}

interface Transformer<S, T> {
	T invoke(S s);
}

enum Color {
	BROWN(Flavor.CHOCOLATE), RED(Flavor.STRAWBERRY), WHITE(Flavor.VANILLA);
	final Flavor flavor;

	Color(Flavor flavor) {
		this.flavor = flavor;
	}
}

enum Flavor {
	CHOCOLATE(Color.BROWN), STRAWBERRY(Color.RED), VANILLA(Color.WHITE);
	final Color color;

	Flavor(Color color) {
		this.color = color;
	}
}

I think I have already seen such a backport already, but here it is again…

Automatic Resource Management blocks

December 30th, 2007

In his (perhaps successful) attempt to sink the BGGA proposal, Captain Bloch send the closuralists packing to Scala island in the Swiss Sea and promised milk(CICE) and honey(ARM) for the rest.

Besides some remaining choices of freedom a ARM block will look somehow like this:

do (InputStream in   = new FileInputStream(src);
    OutputStream out = new FileOutputStream(dest)) {
  byte[] buf = new byte[1024];
  int n;
  while ((n = in.read(buf)) >= 0)
    out.write(buf, 0, n);
}

I thought this should be pretty easy to imitate in Scala as well. Ideally I’d like to have

with (fi<-  new FileInputStream(src);
      fo<- new FileOutputStream(dest)) {
  val buf = new Array[byte](1024);
  def cp() {
    val n = fi.read(buf)
    if (n>0) {
      fo.write(buf,0,n)
      cp
   }
  }
  cp
}

But writing a “with” is not possible - the 2nd idea was to have a with where the resource is “this”:

with (new DbConnection) {
  executeUpdate("delete from scratch")
  commit()
}

As Jamie Webb pointed out a simple wrapper is easy to write and might do the job:

class ManagedResource[T<:{def close()}] (resource:T) {
  def foreach(f : T => Unit) : Unit =
    try {
      f(resource)
    } finally {
      resource.close()
    }
  }
}

and so it is easy to write:

for(pi<-new ManagedResource(new PipedInputStream);
    po<-new ManagedResource(new PipedOutputStream(pi))) {
  po.write('A');
  Console.println((pi.read).asInstanceOf[Char]);
}

So interesting part it: How does this magic work. On Scala island everybody knows swiss-army knives. We usually use “for”. The code above is equivalent to

for(pi<-new ManagedResource(new PipedInputStream)){
    for(po<-new ManagedResource(new PipedOutputStream(pi))) {
  po.write('A');
  Console.println((pi.read).asInstanceOf[Char]);
    }
}

and each block (or closure) is passed to foreach:

new ManagedResource(new PipedInputStream).foreach(pi=>
  new  ManagedResource(new PipedOutputStream(pi)).foreach(po=>{
     po.write('A'); //where is po defined?
     Console.println((pi.read).asInstanceOf[Char]);
   }
  )
)

Here you see the for-magic in action. For defines some nice symbols pi and po for us that make writeing the function much easier than wrapping it all up in nested anonymous functions.

As the expansion of for shows we are getting the nest of resources as we would get if we would write everything by hand. Less visible is the cleanup. Note that the argument to each foreach is a closure. This means th code is excecute where it is writen and not evaluated and then passed to foreach. By this the finally block in foreach executes two times:

  1. After the print
  2. After po had been closed

So far so simple, but why some might ask can I refer to pi and po as PipedInput/Outputstreams instead of ManagedResource[T]s?

The reason is that “for” is just some compiler magic, what eventually gets executed is the foreach which takes a function T=>Unit (i.e. a funtion with a single argument of type T and return value void). T here is either PipedInputStream or PipedOutputstream and the pi and po are type to accommondate for that.

In practice it is a bit more complicated to define ManagedResource because there are three different possible expansions (via map and flatMap). We investigated as well lazy resource acquisition, but this might open some other wholes, but it is possible to write ManagedResources that aquire the underlying resource iff it is accessed. You opening a ctor to the application developer is too dangerours as inadvertedly an open resource might get passed to the ManagedResource without that it can tell that it got already opened.

Resources with explicit open methods as Josh mentioned in his text would solve this problem easily with no overhead for the application developer. An alternative are Linear Types, but that doesn’t go well together with a language like Scala.

Not only open source

December 27th, 2007

I pulled out an old issue of brand eins which remained still unread in the pile of magazines. If you don’t now this magazine yet and you have some interest in off-beat economics and you can read german - get it.

An article with interview with Don Tapscott on his Wikinomics I found quite interesting. The point -in short - is that openess will make you advance quicker and be more successful. I don’t buy everything he says, but he is right in many aspects.

Take the simple example of open source and closed source. Where do you think hides the worst coding and design? It cannot be generalized of course, but closed source has better to get away bad coding. There are exceptions in any domain, Axis for example (at least the 1.4) is a kludge and some closed source stuff I worked on had been beautifully engineered. Anything has to stand the test of time, thus in an active open source problems will be addressed - if not god-like committers reject these changes.

And here I lost interest in continuing until I found Why giving away your code is not dangerous.

Read the rest of this entry »

Acid2

December 25th, 2007

A week ago Microsoft’s IE8 team announced that they passed the ACID2 test. Now - nice present for Xmas - Safari for Windows Beta 4 renders it correctly as well.I checked with Firefox 2.0.0.11 and it is all but OK:acid2.PNGAnyone tried it with other browsers?

Yes, me too! Java is too …

December 25th, 2007

It became irresitable, whenever someone hit a wall in Java or found a nice hack for a specific problem in some other language: Start bashing Java.

In short: If you are still using Java you are

  • … a poorly educated retard
  • … an ignorant who will never see the light
  • … doomed as you programs are unmaintainably bloated
  • … to lazy to write unit tests that replace the declaration of the receiving type in every place
  • … should read “my” blog and stand still in awe

I think this list can be prolonged at will - and it will.

The world is more complicated - fortunately I’d say. Some truths aren’t negotiable:

  • There are programs of different complexity
  • There are programmers of different skill

even more, as slight variations of these

Java should stay Java (?|!)

December 16th, 2007

Josh Bloch’s talk at Javapolis caused quite a stir in the blogosphere, why is best summed up in a blogpost and its comments: Is Java a simple, less skill demanding language or is it - better can it be - also a home for programming geeks.There are two sides and a point can be made for both of them. As java had been need it was a geeky language - admittedly fueled by the internet hype - which attracted brillant minds. Thanks to these forerunners Java is now one of the top choices for mainstream programming. The ones of these who still stick around in the Java world now look with envy on Ruby, Scala and sometimes back on Smalltalk and want to use the ideas and techniques prevalent there in Java as well. But in practice - unless you happen to work at Google - most java programmers are not of this class. Big application written in Java are written and maintained by ordinary developers, not übergeeks that think in monads.The typical Java programmer in a large enterprise is more of the type of the VB programmer, perhaps he did some C or COBOL before. These people and their thinking about programming is deeply rooted in imperative style.A point could - and personally I think it should - be made if projects really require such large staff and if it weren’t better to use more advanced stuff to build it with fewer, but appropriately skilled developers (this is the Ruby claim), but face it, the enterprise world changes too slowly to accomondate for that.More than 10 years ago we evaluated some new development environments as a replacement for Oracle Forms 3. The most interesting candidates had been Forms 4.5 (obviously), Smalltalk (I don’t remember the vendor) and Franz Allegro CLOS (Ok, this had been the one I fancied). Java had been 1.1 or so in these days and the first looks at it were disappointing, C++ had been already in use, but there had been so many problems with it that it wasn’t ever really a consideration. Eventually we went for Forms because it would give our staff the easiest transistion. The main problem with Smalltalk and CLOS had been the paradigm shift. Neither the pure OO of Smalltalk nor the functional programming in Lisp were accessible to them.I think that the same could happen to Java if all the fancy functional programming (I love it!) would get into it. There are three problems

  • FP is not compatible with the mindset of the majority of enterprise programmers. Also FP programs are harder to debug - this is a problem for the prevalent trail-and-error programmer (aka debugging into existence)
  • Java is not Scala, one problem of BGGA is the non-local return. This isn’t an issue in true FP languages which are expression oriented, the statement oriented Java makes it awkward to deal with it
  • DSLs are in fashion and a powerful concept for layering a complex application, but they create as well new languages: You can’t hire a Lisp or C++ programmer and expect him to be immediately productive as they have to learn the DSLs of your projects first

I initially found CICE (which Bloch promotes) to come a bit short, but now I am convinced that this is the right way to change Java as it keeps the characteristics of the language and can easily integrate into larger teams in any organization.This is the curse of being a mainstream language, you most not let out you users in the cold.For the other classes of problems languages like Scala that run on the JVM could be chosen. There some research has to be done by the system architect(s) how such code can integrate with Java code and how maintenance can be organized. This isn’t a trivial problem as not everything from another JVM language integrates seemlessly with Java code (i.e. you use this code as if it was written in Java), as well the question has to be answered (in each indiviual organization) if there is enough stability in the project to support an other language throughout the life-cycle - imagine a freelancer writing some core code in a language only known by him.

Social Stalking

December 7th, 2007

Social networks allow a new way of spamming. Today I got followed by a “network” on twitter. I don’t really use twitter at all, luckily there is a block function on followers. I wouldn’t mind (and I really don’t) if someone is folling me, but doing so just to make me click his website. This is pathetic.  The name of the site is

E x p a t a c u l a r

Sorry for the horrible layout, but I want to avoid that this page will show up even on position 85  in a Google search. Yes, these jerks are horribly successful, 84 hits in Google - and perhaps 3-4 related to the site…

The clever thing thought is that they chose a name that is distinguishable from ordinary expressions. For example: You write a great Webframework and name it lift - googling for it is difficult, because there are so many stories and services about elevators.

Spam salad

December 6th, 2007

Spam belongs in the kitchen…
spamsalad.PNG

Social (music) networks

December 3rd, 2007

One of the few sites I check every other day is Ehrensenf (an anagram of “Fernsehen” = TV, where “Ehrensenf” is something like “Mustard of Honor” - “mustard” is also used in some expression “seinen Senf dazu geben”: to make an irrelevant contribution). There I learned about Jango and immediately became a big fan.

Ehrensenf is feature on the website of the German news magazin Der Spiegel, which also hosts the german edition of Last.fm.  To close the list, also found by Ehrensenf Social.fm. This is how the web works - the good old web 1.0. It simply works.

Let me compare these. Last.fm is for me important as the broadcast as well German music - I swear it got better in the last years; now where thay stopped copying the style of british/US music and use rhytms that fit the German language  some really good bands pop out (Wagner knew this more than a hundred years ago)

Social.fm

Well, I would say it is file-sharing via streaming. Hard to find any social component in it. Yes, you share you playlists with friends, but besides that you don’t get anything back. Their player for Windows looks nice though. The use of the site - simple incomprehensible. I ask myself if they actually have any users besides me. Only mainstream music can be found, if you enter anything not yet streamed by a user the website gets a bit confused - or is it justme?

 Last.fm

Very broad choice of music. Social component virtually zero. But good music anyway. But barely customizable. You can’t specify what you want to hear 80% of the music played would be considered as spam if sent as email. No wonder that the buy-button is always well exposed, especially if you are looking for something specific. Good point Wikis for the bios.

Jango.com

No fm-domain, these guys have no clue… But their site is the best. Some rough edges in the handling of the back buttons, but atleast they are honest enough to say that they’re still beta. You can create many “stations” which are fuzzy playlists, nice visualization of your likes(by a tag-cloud - as here in the sidebar). For each song you play you see other user that play the same at the very moment, a click and you see what else the like, this gives youone or the other idea - I discovered “We are Scientists” by that

Conclusion Jango gets the cake, despite them having the smallest repetoire of all. But they know toleverage the social graph by creating it. It is more interesting to learn something new on the net than just re-reading what you already know about your friends & family.

Social.fm has even an application for facebook. YAFA (Yet Another Facebook Application). I think this kind of social networking serves only the owner of the site for targeting advertisment - I haven’t seen any facebook app that could make any use of the great social graph - at best the social graph is used to invited friends of your to use the same stupid app you are using at the moment.

Traits and extension-methods in plain Java

December 3rd, 2007

Original problem: You have a simple hierarchy, class B extends A. Now your simple program needs customization for a client. You create CA extends A. Now should B extend CA or A?

This was the simple part. Now we expand our business to serve martians. Lets extend A by M. But the mars is a region and for customers on mars we’ll have MA. You get the idea. In terms of product line management it gets messy when juggling with these inheritances. Sooner or later it won’t work anymore - hopefully soon enough before millions of lines of code had been duplicated.

OK, it boils down again to prefer composition (by delegation) over inheritance. But it is ugly and hard to maintain. In most case the concept of Traits is sufficient. Scala is using traits extensively and the syntax is vey nice. I looked for a way to achieve something similar in Java. The result is my first code.gogle.com project: Open-Traits.

Here in short how it works. We have some class Cx implementing interface U,V,W,X. We can factor now a traited object by:

  Traits ts = new Traits()
    .with(new CU())
    .with (new CVW())
    .with(new CUX());
  Object traited = t.traited();

The object traited is a Proxy which does all the plumbing for us and we can simply downcast it to:

  U u=(U)traited;
  V v=(V)traited;
  W w=(W) traited;
  X x=(X) traited;

It would be nice to define a type “Vuxw” that extends all these interfaces, but the current implementation doesn’t support that - more a choice on my behalf than some impossible*

Of course our traits CU,CVW,CUX have to obey some rules, if they all inherit Trait the above could be written as

  Traits ts = new Traits();
  new CU(ts);
  new CVW(ts);
  new CUX(ts);

There are many other things that can be done (and things that can’t be done) - check them out in the API doc available on the project site.

Something very special are trait-super and trait-virtual methods. If CU contains a call to a metod defined by U it is possible that our Traits can virtualize it and make CUX’s implementation being called, conversely CUX can call “super.u()” (in Open-Traits overriden().u()) to call the method defined in CU. Pretty nifty, isn’t it?

It gets even better : If we kept a reference to the new CUX instance, cux we could do:

  ts.remove(cux);
  ts.with(new MyCUX());

This means we can change (in some save limits) the traits composition. This is a great tool to create Adapters and Visitors which might come handy when writing interfacing modules.

I am aware that using another language would be more elegant and more efficient, but let us not get too greedy. It took quite a time to convince people that valuable software can be written in other languages than COBOL .

*Fixed Traits

I am planning to write an alternative to Traits, FixedTraits. A fixed trait will be a generic class of type T which is instantiated as

new FixedTraits<U,V,W,X> where the method traited() has the type <T extends U,V,W,X>. This would save the casts to the result of traited and is thus more type-safe. But it is as well much uglier at other parts. As well the dynamic add/removal will pperhaps be lost. It would be much easier if two things existed in Java had Interface compositions. BTW: Scala solved this problem elegantly: You never declare it, you rely on typ-inference