Thursday, February 28, 2013

Neues Blog zur funktionalen Programmierung

Wir haben ein neues Blog!

Zusammen mit der active group GmbH zeigen wir im neuen Blog jede Woche an Beispielen Vorteile und Einsatzgebiete der funktionalen Programmierung auf. Wir möchte über diese neue Platform das Wissen teilen, das wir im langjährigen, kommerziellen Einsatz dieser Techniken erworben haben. Wir hoffen, dass unsere Erfolge und guten Erfahrungen helfen können auch andere deutsche Softwareentwickler und Firmen zu ermutigen funktionale Programmierung einzusetzen.

Trotz des neuen Blogs werden wir weiterhin auf dem Firmenblog hier interessante technische Aspekte und Firmenneuigkeiten mit unseren Lesern teilen. Artikel über funktionale Programmierung werden aber schwerpunktmäßig im neuen Blog zu finden sein. Es lohnt sich also in Zukunft beide Blogs zu abbonieren.

Sunday, July 19, 2009

Discussing the colour of the new bikeshed

Ich weiss eigentlich gar nicht wie häufig wir betroffen sind, aber darüber nachzudenken wann man wie viel über was diskutiert ist sicherlich nicht falsch. Kurz gefasst: es geht um "Parkinson's Law of Triviality" von 1957, das besagt, dass die einfachsten, unwichtigsten Fragen, die meiste Aufmerksamkeit bekommen und sehr lange Diskussionen hervorrufen, weil jeder dazu eine Meinung haben kann und sich einbringen möchte.

Damals wurde es von Parkinson mit Bezug auf Entscheidungen in Aufsichtsräten formuliert aber besonders bekannt geworden ist es durch Poul-Henning Kamp von FreeBSD, der meinte das lange belanglose Mailinglistendiskussion der Gemeinschaft schaden: http://www.bikeshed.com/

Autor: David Leuschner

Sunday, April 26, 2009

Some Java Fun becoming a major pain

Ich hab mal wieder mit GWT rumgespielt und etwas Java programmiert. Da ich ohne map, fold und filter nicht mehr auskomme und Java ja endlich Generics hat, hab ich mir eine kleine Fun Library geschrieben, damit ich z.B. sowas machen kann...

Set<String> strSet = Fun.mapS(intSet, new Fun<String,Integer>() {
  public Integer eval(String s) { return Integer.parseInt(s); }
});

Das funktioniert auch ganz gut, auch wenn die Syntax alles andere als angenehm ist. Ich hab also eine abstrakte Klasse

abstract class Fun<A,B> {
  public abstract B eval(A x);

mit Hilfsfunktionen wie

public static <A, B> Set<B> mapS(Collection<A> src, Fun<A,B> fun) {
  // ...
}

Wenn man eine Mapping-Funktion mehrfach braucht muss man sie auch nicht immer inline-definierien, sondern kann eine Konstante draus machen, also z.B. im Beispiel oben

Fun<String,Integer> STR_TO_INT = new Fun<String,Integer>() {
  public Integer eval(String s) { return Integer.parseInt(s); }
};

und dann braucht man nur noch

Set<String> strSet = Fun.mapS(intSet, STR_TO_INT)

schreiben. Alles wunderbar... nur dann brauchte ich eine Funktion um aus Map.Entrys die erste Komponente zu extrahieren (map.entrySet() ging in dem Fall nicht). Also

Fun<Map.Entry<String, Integer>, Integer> ENTRYKEY =
  new Fun<Map.Entry<String, Integer>, Integer>() {
    public Integer eval(Map.Entry<String,Integer> e) {
      return e.getKey();
    }
  };

und das funktioniert auch noch gut. Aber dann brauchte ich die Funktion für andere Typparameter. Na, kein Problem, kann man doch sicher generalisieren:

public static <A,B> Fun<Entry<A,B>, A> ENTRY_KEY_1 = new Fun<Entry<A, B>, A>() {
  @Override
  public A eval(Entry<A, B> x) {
    return x.getKey();
  }

Nur leider kompiliert das nicht. Polymorphe Werte scheint Java nicht zu unterstützen. (Oder hab ich's nur falsch gemacht?!) Okay, also eine Dummy-Funktion....

public static <A> Fun<Entry<A>, A> ENTRY_KEY_2() {
  return new Fun<Entry<A>, A>() {
    @Override
      public A eval(Entry<A> x) {
      return x.getKey();
    }
  };
};

Die kann man definieren, aber leider nicht aufrufen!

Pain.java:38: <A>mapS(java.util.Collection<A>,Fun<A>) in Fun cannot
be applied to
(java.util.Set<java.util.Map.Entry>,Fun<java.util.Map.Entry,java.lang.Object>)

Wahrscheinlich weil nur anhand der Parameter die richtige Belegung ausgewählt werden kann. Also muss man einen Phantom-Parameter einführen...

public static <A> Fun<Entry<A>, A> ENTRY_KEY_3(Entry<A> phantom) {
  return new Fun<Entry<A>, A>() {
    @Override
      public A eval(Entry<A> x) {
      return x.getKey();
    }
  };
};

und dann beim Aufruf

Set keys = Fun.mapS(map.entrySet(), ENTRY_KEY_3((Entry) null));

Oh.... das tut weh!

Weiss jemand wie das mit Generics in C++ und C# ist? In Scala geht das sicher, oder?

Schade, dass GWT Java SourceCode nach JavaScript kompiliert und nicht, wie ich dachte, Java ByteCode. Damit man mit GWT in den Genuss von Scala kommt muss man wahrscheinlich erst Scala nach ByteCode komilieren und dann mit einem Dekomiler aus dem ByteCode wieder JavaCode machen und den dann mit GWT kompilieren. Oder man hackt gleich getyptes JavaScript in Haskell aber Dmitry Golubovsky ist nicht Google und Version 0.1 ist wohl eher ein Proof of concept. Wahrscheinlich sollte ich halt doch einfach schön imperativ in Java programmieren und Generics nur verwenden um ein paar Casts zu sparen. :-/

Autor: David Leuschner