Filesharing und freie Inhalte

written by Martin Häcker on

Nachdem die Musikindustrie immer noch nicht einsieht das Massenklagen gegen die eigenen Käufer letztlich kein Mittel sind diese in 'willig zahlende Käufer' zu verwandeln (Kunden finde ich als Wort dafür schon zu gutwillig) kann ich nur sagen das ich mich immer weiter davon entferne überhaupt Content zu konsumieren der unter solchen restriktiven Lizenzen steht.

Für Video gibt es iTunes oder was ich heute wiederentdeckt habe Projekte wie den Democracy Player.

So. Jetzt geh mir zum Teufel Industrie.

p.s.: Freie inhalte gibts ja auch in der Forschung. Leider hat noch nicht jeder Wissenschaftler die Möglichkeit frei nach denOpen Access Prinzipien zu veröffentlichen. Das ist vor allem bedenklich, da die Veröffentlichungsindustrie die um die Wissenschaften gewachsen ist monopolartige Strukturen angenommen hat.

Gott sei dank gibt es aber eine Petition großer Wissenschafatsverbände in Deutschland durch den DFG vertreten die sich für eine gesetzliche Grundlage für Wissenschaftler einsetzen das diese ihre Papers nach 6 Monaten per Open Access Veröffentlich können.

Unbedingt unterschreiben.

Demokratie und Zukunft

written by Martin Häcker on

Demokratie scheint ja (leider nicht nur in Deutschland) überhaupt keine Zukunft zu haben. Zu sehen sind immer nur noch immer stärkere Bewegungen hin zum Überwachungsstaat.

Aber, es tut sich doch zumindest etwas, z.B. gab es heute einen Artikel in Telepolis der klar macht was bei einem vernünftigen Einsatz neuer Technologien in der Politik heute eigentlich möglich wäre.

  • Parteien sind eigentlich ein Auslaufmodell, weil sich jeder Wähler für ein Komplettpaket an politischen Maßnahmen und Ideologien entscheiden muss, womit er immer zumindest teilweise gegen seine eigenen Interessen handeln muss.
  • Vollständig repräsentative Demokratien sind aus der notwendigkeit geboren schnell Entscheidungen treffen zu müssen, Informationen aber sehr langsam 'reisen'.

Das sind alles Dinge die so nicht mehr stimmen - Informationen sind schnell. In einer Sekunde reisen sie Vielmahls um die Welt. (Ja ok, wären wir in einer Intergalaktischen Demokratie, dann wäre das was anderes, aber....)

Diesen Entwurf sollte man sich mal auf der Zunge zergehen lassen!

iTunes style progress-bar

written by Martin Häcker on

Image Just as an exercise I ripped the progress bar rendering code out of MPlayer and generalized it, fixing some 10 to 15 bugs in the process. Though I couldn't get it back into the MPlayer source (yet!) its already going into other software, most notably Senuti. So if you need such a progressbar, have phun!

As I'm still gearing up on my graphics programming, there is still the unesthetic choice in there to use pictures for some of the interface elements. So, free after Wil Shipley thats a no no. :) If you (the reader) care and could send me a patch, that would be greatly appreciated.

Technisch Präsentieren

written by Martin Häcker on

In meiner Freizeit (Notiz an selbst: Ich hab zu viel Zeit) bereite ich gerade einen Javakurs für frische Informatiker vor, genauer solche die gerade mit dem zweiten Semester anfangen.

Dafür interessiere ich mich jetzt natürlich in der guten Präsentation dieses, doch eher "technischen" Themas.

Hervorragend gefallen hat mir da der Didaktische Ansatz von Head First Java, und ein schon Jahre-Alten Papers von Jay H. Lehr: Let There Be Stoning.

Aspekt-Orientiertes Programmieren

written by Martin Häcker on

Tja, da denkt man jahrelang, das AOP halt ein ganz nützliches Tool zum Loggen ist, da schreibt doch endlich mal jemand wofür das so alles gut ist und man fängt an sich über Meta-Programierung und den Ursprung von AOP - dem Meta-Objekt-Protokoll - Gedanken zu machen.

Funktionen als voll berechtigte Datentypen

written by Martin Häcker on

Funktionale Sprachen erhalten ihre Eleganz dadurch, dass sie die Programmierung mit Funktionen als Argumente und Rückgabewerte erlauben. Schön erklärt wird das im SICP. Tatsächlich kann das so weit gehen, dass zum Beispiel in Lisp gar kein Unterschied mehr zwischen Funktionen und beliebigen Daten gemacht wird. Aber das ist zugegebenermaßen extrem.

Für die Kürze nennt man diese Art zu programmieren auch gerne: "Higher-Order-Programmierung" und die entsprechenden Funktionen "Higher-Order-Funktionen".

In der Imperativen Programmierung werden Funktionen als Argumente oder Rückgabetypen eher selten verwendet. In C gerade noch beim Standard-Algorithmus Binary-Search

void *
bsearch(const void *key, const void *base, size_t nmemb, size_t size,
         int (*compare) (const void *, const void *));

bei dem die compare-Funktion genau so eine Higher-Order-Funktion ist. Danach ist es aber erstmal lange zappenduster, was Higher-Order-Programmierung angeht. (Hervorragende Programmierer nutzten dieses Design-Pattern aber schon immer - wenn es auch selten explizit genannt wurde)

So kam es dann auch, dass manche objektorientierten Sprachen Objekte wie Knöpfe, Textfelder etc. hatten, die man ableiten konnte, um ihr Verhalten zu verändern. Java etwa erlaubt das noch heute:

// Java
class OKButtonForThatSpecificDialog extends JButton {
    public void doClick() {
        System.out.println("Yay, I was clicked");
    }
}

Zwei Probleme ergeben sich aus dieser Art zu programmieren:

  • Erstens: jede Menge duplizierter Code, der größtenteils identisch ist. Damit erlebt man einen Alptraum, sobald man auch nur daran denkt, etwas Grundlegenderes an dem Programm zu ändern.
  • Zweitens ist der Code, der tatsächlich die Kontrolle über das Programm ausführt, so in viele Dateien oder zumindest Klassen verstreut, also mitnichten an einer Stelle vereint und übersichtlich.

Beide Probleme kann man mit dem oben beschriebenen Mechanismus der Higher-Order-Funktionen elegant lösen - und tatsächlich wird das auch gemacht. In Inversion of Controll (IOC)-Frameworks etwa. Hier ruft man nicht mehr eine Funktion auf, um ein Ergebnis zu bekommen, sondern konfiguriert den Framework (Knöpfe, Textfelder, etc.) mit eigenen (Higher-Order)-Funktionen, die dieser aufruft, sobald ein Ergebnis oder Ereignis vorliegt.

Absolut typisch für dieses Muster sind alle mir bekannten aktuell verwendeten GUI-Toolkits, die immer so funktionieren, dass man z.B. einen Knopf erzeugt, um danach mit einer (Higher-Order)-Funktion zu konfigurieren, was denn passieren soll, wenn auf ihn geklickt wird.

// Java
JButton button = new JButton("Titel");
button.addActionListener(aClickResponder);
// Obj-C
[aButton setTarget: self];
[aButton setAction: @selector(respondToClick:)];

Aber dieses Muster ist noch viel weiter verwendbar - in Objective-C gibt es eine Möglichkeit, auf alle Elemente eines Containers eine Methode doSomethingWithEachElement: anzuwenden, die ein Argument - das jeweilige Element - erhält.

// Obj-C
[aList makeObjectsPerformSelector:@selector(doSomethingWithEachElement:)];

Äquivalent läuft das in den GUI-Toolkits von Java, Cocoa, Gnome, KDE, WxWidgets...

Fortgeschrittenere Sprachen und Toolkits verwenden dieses Design-Pattern auch noch an vielen weiteren Stellen. Besonders hervorzuheben ist dabei in letzter Zeit Ruby, wo nach diesem Muster nicht nur Iteration, sondern auch das Bearbeiten jeder Zeile in einer Datei, das Senden von Daten über einen Socket, ... verläuft.

Am extremsten ist aber vielleicht die Sprache Smalltalk, wo es überhaupt keine normalen Kontrollstrukturen im Sinne von C/Java mehr gibt und diese Aufgabe komplett durch Higher-Order-Funktionen erledigt wird. Hier gibt es beispielsweise ein Boolean Objekt, das eine Methode #ifTrue:ifFalse: besitzt. Diese Methode bekommt dann zwei Callbacks übergeben und führt je nachdem, ob es das True- oder das False-Boolean ist, polymorph den jeweils anderen Callback aus. - Analog werden Schleifen, Exception-Handling... einfach alle Kontrollstrukturen definiert.

Das nette daran: Damit kann man innerhalb der Sprache selber Kontrollstrukturen definieren. Schick, nicht?

Umsetzung

Um mit Higher-Order-Funktionen in Java / Obj-C zu programmieren, kann man z.B. so vorgehen:

// Obj-C
 - (void) setAction: (SEL) aSelector forTarget: aTarget {
    action = aSelector;
    target = aTarget;
 }

 - (void) trigger {
    if ([target respondsToSelector: action]) {
        [target performSelector: action];
    }
 }
// Java
 void setActionListener(ActionListener listener) {
    this.listener = listener;
 }

 void trigger() {
    listener.actionPerformed(null);
 }

Das wars - so einfach geht das.

TODO: Auf [http://libsigc.sourceforge.net/libsigc2/docs/manual/html/ch02.html] verweisen und vergleichen wie Callbacks mit sowas und (beste C++ Callback Bibliothek) gehen. Vergleichen wie echte Lambdas das leichter machen können.

Neue Religionen...

written by Martin Häcker on

...sind sicherlich heute sehr selten.

Tja, denkt man. Leider.

Wo ich gerade beim Thema sind... Jeder sollte sein Softwarepatent des Monats wählen!

How to fold a shirt

written by Martin Häcker on

[/blog-attachments/videos/HowToFoldAShirt.mpg Hausahltsanleitung....]

Unterdokumentierte Design Patterns

written by Martin Häcker on

Eine Frage die mich schon länger beschäftigt, ist das Finden von Design Patterns in Funktionalen Sprachen. Lange Zeit schien es mir so, als gäbe es da gar nichts, auch viele Programmierer, die in diesen Sprachen arbeiten, konnten mit dem Begriff nichts anfangen. Dabei gibt es meiner Meinung nach eine Menge, das man von funktionalen Sprachen lernen kann - und einiges, das schon gelernt wurde.

Einige Design Patterns, die ich seitdem gefunden habe, sind:

  • [wiki:BlogEntries/2006-02-23 Funktionen] als voll berechtigte Datentypen, d.h. man kann sie als Argument oder Rückgabewert in der Programmiersprache verwenden
  • Die Verwendung von Lambda-Ausdrücken (anonymen Funktionen)
    • Für Iteration, als Callback, für Fehlerbehandlung, Kontrollfluss...
  • Higher Order Funktionen - Funktionen als Argument und Rückgabewert von Funktionen
  • Currying zum teilweisen Anwenden von Funktionen (vor allem in Zusammenhang mit anonymen Funktionen interessant)
  • Funktionen zur Kombination von Funktionen zu größeren Einheiten (sehr schön z.B. in Parsern)
  • Monaden, zum sicheren Einbetten von Seiteneffekten in puren funktionalen Sprachen
  • Arrows, für sichere Nebenläufigkeit in puren funktionalen Sprachen
  • Unendliche Listen als Fassung von Reihen von Zahlen / Ereignissen. (Aktionen des Benutzers, Zufallszahlen, stetig genauer werdende Berechnungen einer Zahl...)
  • Continuations: Ein Konstrukt mit dem sich z.B. Exceptions und Coroutinen implementieren lassen
  • Coroutinen: Am einfachsten als eine Art Ultraleicht-Thread zu verstehen

Einige dieser Design Patterns werden auch in anderen Sprachen intensiv genutzt. Die Lambda-Abstraktion zum Beispiel spielt eine zentrale Rolle in Java, wenn man dort GUIs baut, da sie der ideale Callback sind. Also im Beispiel:

JButton button = new JButton("Titel");
button.addActionListener(new ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent e) {
        // this is a lambda
    }
}

Gibt es noch mehr dieser Design Patterns? Funktionale Sprachen werden doch von jeder Menge Menschen benutzt...

Sind die irgendwo dokumentiert? Wenn nicht, dann muss ich mich wohl ranhalten und mein Verständnis selber aufschreiben.

Außerdem haben hochintegrierte Sprachen wie Lisp, Scheme, Smalltalk und Ruby noch ein weiteres Pattern, da sie sich besonders gut (oder überhaupt?) dazu eignen, Domänenspezifischen Subsprachen (DSL), also Sprachen die direkt in der Implementierungssprache eingebettet sind, zu formulieren. In Lisp bzw. Scheme ist das sogar die bevorzugte Vorgehensweise!

Mir ist allerdings noch nicht klar, welches Kriterium eine Sprache in die Lage versetzt, diese Integrierten DSLs besonders gut umzusetzen. Bisher dachte ich immer, dass dazu eine in ihrer Übersimplifizierung geniale Sprachdefinition - wie in Lisp und Smalltalk - notwendig ist, aber gerade das Beispiel von Ruby scheint dem zu widersprechen.

Preisfrage

written by Martin Häcker on

Man hat 8 Billiard-Kugeln, von denen man weiß das eine schwerer ist als die Anderen. Desweiteren hat man eine Balkenwage mit der man zwei mal Wiegen, also zwei Gewichte vergleichen, darf.

Lässt sich unter diesen Vorraussetzungen herausfinden welche Kugel die schwerere ist?

Viel spaß beim Raten. :)

Oh, and by the way: TCPA ist immer noch doof: Erklärender Film