<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
    <channel>
        <title>Blackflash</title>
        <description>Blog über Informatik, Software, Projekte und alles Interessante.</description>
        <link>http://blackflash.nordic-dev.de/feed.php?type=rss&amp;tag=</link>
        <lastBuildDate>Mon, 21 May 2012 12:38:58 +0200</lastBuildDate>
        <generator>Wordcraft 0.8</generator>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/nordic-dev" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="nordic-dev" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
            <guid>http://blackflash.nordic-dev.de/linktipps-mai-2010</guid>
            <title>Linktipps Mai 2010</title>
            <link>http://blackflash.nordic-dev.de/linktipps-mai-2010</link>
            <description><![CDATA[<ul>
    <li>
        <a href="http://lwn.net/Articles/379329/">Should web
        developers say no to cookie-based authentication?</a>: Was
        sind bei der Authentifizierung die Alternativen zu Cookies
        und sollte man diese den Cookies vorziehen? Zwar sollte
        diese Frage jeder für sich selbst beantworten, aber ich
        finde, dass dieser Artikel einige Denkanstöße gibt.
    </li>

    <li>
        <a href=
        "http://blog.sigfpe.com/2010/03/partial-ordering-of-some-category.html">
        A Partial Ordering of some Category Theory applied to
        Haskell</a>: Aufgrund des großen Interesses an
        kategorientheoretischen Anwendungen in Haskell hat Dan
        Piponi eine Sammlung seiner Artikel, die sich mit
        Kategorientheorie beschäftigen, zusammengestellt.
    </li>

    <li>
        <a href="http://brian.moonspot.net/devops-dealnews">DevOps
        at dealnews.com</a>: Brian Moon plaudert aus dem
        Nähkästchen über das Deployment bei <a href=
        "http://dealnews.com/">dealnews.com</a>.
    </li>

    <li>
        <a href=
        "http://blog.melding-monads.com/2010/04/04/on-powersets-and-folds/">
        On powersets and folds</a>: Wer gerne cleveren Haskell-Code
        liest, der ist bei diesem Artikel gut aufgehoben.
    </li>

    <li>
        <a href=
        "http://byorgey.wordpress.com/2010/04/03/haskell-anti-pattern-incremental-ad-hoc-parameter-abstraction/">
        Haskell anti-pattern: incremental ad-hoc parameter
        abstraction</a>: Wie abstrahiert man am besten von einer
        Vielzahl von Parametern? Brent Yorgey beschreibt die
        Lösung: Records mit Data.Default.
    </li>

    <li>
        <a href=
        "http://neilmitchell.blogspot.com/2010/04/file-recovery-with-haskell.html">
        File Recovery with Haskell</a>: Neil Mitchell beweist, wie
        einfach man ein nützliches Werkzeug in Haskell schreiben
        kann: Korrupte Dateien möglichst vollständig kopieren.
    </li>

    <li>
        <a href=
        "http://blog.ezyang.com/2010/04/you-could-have-invented-zippers/">
        You could have invented zippers</a>: In Anspielung auf Dan
        Piponis <a href=
        "http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html">
        You could have invented monads</a> beschreibt Edward Z.
        Yang die Zipper-Datenstruktur unter Zuhilfenahme einiger
        Illustrationen.
    </li>

    <li>
        <a href=
        "http://devzone.zend.com/article/12014-Trait-like-Functionality-for-PHP">
        Trait-like Functionality for PHP</a>: Wer keine Lust hat,
        auf <a href="http://wiki.php.net/rfc/traits">Traits in
        PHP</a> zu warten, der wird diesen Artikel interessant
        finden, da er etwas, was Traits sehr ähnlich ist, anhand
        von PHPs Metaprogrammierung entwickelt.
    </li>

    <li>
        <a href=
        "http://abdullin.com/journal/2010/4/8/couchdb-document-persistence-powered-by-cqrs.html">
        CouchDB - Document Persistence Powered by CQRS</a>: Für
        welche Zwecke ist CouchDB trotz der Vorteile nicht
        geeignet? Dieser Artikel schneidet das Thema an.
    </li>

    <li>
        <a href=
        "http://www.iis.sinica.edu.tw/%7Escm/2010/maximum-segment-sum-origin-and-derivation/">
        The Maximum Segment Sum Problem: Its Origin, and a
        Derivation</a>: Shin-Cheng Mu zeigt, wie man einen
        Linearzeitalgorithmus aus einer Problemstellung fast
        mechanisch ableiten kann.
    </li>

    <li>
        <a href=
        "http://blog.johantibell.com/2010/04/generational-garbage-collection-and.html">
        Generational garbage collection and floating garbage</a>:
        Johan Tibell klärt über einige Aspekte der Garbage
        Collection (des GHC) auf und erläutert, wie man diesen
        Prozess optimieren kann. Für jeden, der mehr über die
        Funktionsweise des GHC lernen will, ist dieser Artikel
        empfehlenswert.
    </li>

    <li>
        <a href="http://www.paulgraham.com/icad.html">Revenge of
        the Nerds</a>: Paul Graham erlï¿½utert vor allem die
        Ausdrucksfähigkeit verschiedener Programmiersprachen und
        die daraus folgenden Konsequenzen. Jeder, der Software
        schreibt, sollte sich diesen Artikel durchlesen!
    </li>

    <li>
        <a href=
        "http://blog.couch.io/post/511008668/nosql-is-about">NoSQL
        is About?</a>: Worum geht es beim vielfach erwähnten NoSQL?
        Jan Lehnhardt klärt diese Frage mit einem einfachen Satz:
        <em>Bei NoSQL geht es um Auswahl</em>. Wer diesen Satz
        verstehen möchte, sollte unbedingt seinen Artikel lesen.
    </li>

    <li>
        <a href=
        "http://just-bottom.blogspot.com/2010/04/programming-with-effects-story-so-far.html">
        Programming with effects - the story so far</a>: Jeder
        Haskellentwickler kennt Monaden, aber es gibt noch
        allgemeinere Konzepte, die sich mit Seiteneffekten
        befassen. Patai Gergely hat dazu ein anschauliches Diagramm
        angefertigt und erklärt die im Diagramm dargestellten
        Beziehungen.
    </li>

    <li>
        <a href=
        "http://blog.ezyang.com/2010/04/inessential-guide-to-data-accessor">
        Inessential Guide to data-accessor</a>: Wer die nativen
        Haskell-Records unschön findet, der sollte sich diesen
        Artikel durchlesen, denn er gibt eine schöne
        Zusammenfassung über die <a href=
        "http://hackage.haskell.org/package/data-accessor">data-accessor</a>-Bibliothek.
    </li>

    <li>
        <a href=
        "http://byorgey.wordpress.com/2010/04/15/cabal-init/">cabal
        init</a>: Ein Muss für jeden angehenden Haskellentwickler.
    </li>

    <li>
        <a href=
        "http://blog.orfjackal.net/2010/04/direct-and-indirect-effects-of-tdd.html">
        Direct and Indirect Effects of TDD</a>: Neben den Effekten
        von testgetriebener Entwicklung bietet dieser Artikel auch
        einen allgemeinen Einblick in die Softwareentwicklung.
    </li>

    <li>
        <a href=
        "http://changelog.complete.org/archives/1463-moral-obligations-of-free-software-authors">
        Moral obligations of Free Software authors?</a>: Ist man
        als Autor freier Software moralisch verpflichtet, die
        Verantwortung für sein Projekt zu behalten, wenn diese
        Aufgabe niemand aus der Community übernimmt? John Goerzen
        schildert dieses Dilemma aus seiner Sicht. Auch lesenswert
        sind die unterschiedlichen Meinungen in den Kommentaren.
    </li>

    <li>
        <a href=
        "http://fabien.potencier.org/article/43/find-your-files">Find
        your Files</a>: Fabien Potencier stellt die Symfony
        Finder-Komponente vor, die mir durchaus gelungen erscheint.
    </li>

    <li>
        <a href=
        "http://blog.ezyang.com/2010/04/creative-catamorphisms/">Creative
        catamorphisms</a>: Edward Z. Yang erläutert kurz den
        Begriff <a href=
        "http://en.wikipedia.org/wiki/Catamorphism">Catamorphismus</a>,
        um kreative Catamorphismen mit Bezug auf <a href=
        "http://groups.csail.mit.edu/mac/users/gjs/6.945/readings/MITApril2009Steele.pdf">
        Guy Steeles Präsentation</a> zu beschreiben.
    </li>

    <li>
        <a href=
        "http://blog.ezyang.com/2010/04/the-problem-with-xunit/">The
        Problem with xUnit</a>: Warum sind Unit-Tests suboptimal?
        Edward Z. Yang spricht mir mit diesem Artikel aus der
        Seele.
    </li>

    <li>
        <a href=
        "http://coderoom.wordpress.com/2010/04/22/7-reasons-to-hate-your-code/">
        7 Reasons To Hate Your Code</a>: Sieben Gründe, den eigenen
        Code zu hassen? Teils humorvoll, teils ernsthaft begründet,
        gibt der Autor Aufschluss, warum guter Code nicht alles
        ist.
    </li>
</ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sun, 02 May 2010 06:02:00 +0200</pubDate>
            <category>algorithmen</category>
            <category>couchdb</category>
            <category>datenbanken</category>
            <category>haskell</category>
            <category>kategorientheorie</category>
            <category>links</category>
            <category>php</category>
            <category>softwaretechnik</category>
            <category>theorie</category>
            <category>web</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-april-2010</guid>
            <title>Linktipps April 2010</title>
            <link>http://blackflash.nordic-dev.de/linktipps-april-2010</link>
            <description><![CDATA[<ul><li><a href="http://donsbot.wordpress.com/2010/03/01/evolving-faster-haskell-programs-now-with-llvm/">Evolving Faster Haskell Programs (now with LLVM!)</a>: Mit genetischen Algorithmen die Geschwindigkeit eines Haskell-Programms verbessern? Don Stewart zeigt, wie er es geschafft hat.</li><li><a href="http://tryhaskell.org/">Try Haskell!</a>: Ein interaktives Tutorial in grundlegende Sprachkonzepte von Haskell. Sehr schön, wenn man mal ein wenig ausprobieren möchte, ohne viel lesen zu müssen. Letztendlich kann dieses interaktive Tutorial aber nur einen kleinen Vorgeschmack geben.</li><li><a href="http://bsonspec.org/">BSON - Binary JSON</a>: Diese Webseite enthält sowohl Spezifikationen als auch weitere Informationen zum binären JSON-Format, wie es von MongoDB verwendet wird.</li><li><a href="http://blog.sigfpe.com/2010/02/decategorification-of-naturals.html">The Categorification of the Naturals</a>: Auf Typlevel wird anhand der Peano-Arithmetik ein Isomorphismus zwischen natürlichen Zahlen und Typen entwickelt. Sehr lesenswert für all jene, die von der Mächtigkeit der Typen in Haskell begeistert sind.</li><li><a href="http://blog.sigfpe.com/2009/11/programming-with-impossible-functions.html">Programming with impossible functions, or how to get along without monads.</a>: Pure Funktionen und IO passen nicht zusammen? sigfpe zeigt das Gegenteil. </li><li><a href="http://math.andrej.com/2009/04/09/pythons-lambda-is-broken/">Python’s lambda is broken!</a>: Manchmal führt auch aussagekräftiger Code zu unerwarteten Ergebnissen - wie hier in Python.</li><li><a href="http://math.andrej.com/2009/04/11/on-programming-language-design/">On programming language design</a>: Programmierer werden jeden Fehler machen, den sie machen können. Deshalb sollten Programmiersprachen einen guten Entwurf vorzuweisen haben. Die populärsten Fehler werden in diesem Artikel vorgestellt, mitsamt Beispielen wie auch Lösungen in verschiedenen Sprachen.</li><li><a href="http://www.checkmycode.org/">checkMyCode.org</a>: Wer seinen in C geschriebenen Code überprüfen lassen will, kann dies mit der genannten Webapplikation tun. Als Basis dafür dienen ca. 16 Millionen Regeln, die aus 200 Millionen Zeilen Code von Linux-Programmen extrahiert wurden.</li><li><a href="http://blog.sigfpe.com/2009/12/where-do-monads-come-from.html">Where do monads come from?</a>: sigfpe klärt über Zusammenhänge zwischen Berechnungen, Algebren und Monaden auf - sehr lesenswert für Interessenten der Theorie.</li><li><a href="http://blog.ezyang.com/2010/03/expert-considered-harmful/">Being an expert considered harmful</a>: Die Schattenseiten des Expertentums... Man sollte sich immer wieder daran erinnern lassen.</li><li><a href="http://www.phpclasses.org/blog/post/119-Neural-Networks-in-PHP.html">Neural Networks in PHP</a>: Künstliche neuronale Netze und PHP? Anscheinend ist es doch kein Widerspruch, was dieser interessante Artikel beweist.</li><li><a href="http://chplib.wordpress.com/2010/03/08/synchronous-channels-using-mvars/">Synchronous Channels using MVars</a>: Effiziente Synchronisierung in Haskell. Für jeden, der parallel und beiläufig mit Haskell arbeiten will, bietet der Artikel eine sehr gute Strategie sowie interessantes Hintergrundwissen.</li><li><a href="http://www.julianbrowne.com/article/viewer/brewers-cap-theorem">Brewer's CAP Theorem</a>: Dieser gut recherchierte Artikel bietet einen interessanten Überblick über das CAP-Theorem und adressiert auch die Konsequenzen desselben.</li><li><a href="http://eliw.wordpress.com/2010/03/10/an-intriguing-use-of-lambda-functions/">An intriguing use of lambda functions</a>: Es ist schön zu sehen, wenn Lambda-Funktionen in PHP sinnvoll eingesetzt werden.</li><li><a href="http://www.heise.de/newsticker/meldung/Code-Blasen-statt-Dateien-952006.html">Code-Blasen statt -Dateien</a>: Wer alte Konventionen aufbrechen will, sollte sich diese Innovation ansehen, denn das interessante Vorteile für professionelle Entwickler bieten.</li><li><a href="http://www.alsonkemp.com/haskell/reflections-on-leaving-haskell/">Reflections on leaving Haskell</a>: Welche Gründe könnte man haben, um die Haskell-Community zu verlassen? In diesem Artikel und <em>vor allem</em> in den Kommentaren finden sich viele Probleme, aber auch einige Lösungen derselben, wieder. Für jeden, der einen vollständigen Eindruck der Sprache erhalten will, enthält dieser Linktipp eine Fülle von Informationen.</li><li><a href="http://blog.ezyang.com/2010/03/straitjacket-programming/">Straitjacket programming</a>: Was haben Zwangsjacken mit Programmierung zu tun? Mehr als man denkt! Ohne mehr darüber verraten zu wollen, kann ich den Artikel jedem ans Herz legen.</li><li><a href="http://ivanmiljenovic.wordpress.com/2010/03/15/repeat-after-me-cabal-is-not-a-package-manager/">Repeat after me: “Cabal is not a Package Manager”</a>: Gerade als Einsteiger in der Haskell-Community ist dieser Artikel gut geeignet, da er die Möglichkeiten von <a href="http://hackage.haskell.org/packages/hackage.html">Hackage</a>, <a href="http://www.haskell.org/cabal/">Cabal</a> und <em>cabal install</em> aufzeigt.</li><li><a href="http://lukepalmer.wordpress.com/2010/03/19/haskells-big-three/">Haskell’s Big Three</a>: Luke Palmer hat seine Liste der drei größten Problempunkte in Haskell erstellt.</li><li><a href="http://blog.ezyang.com/2010/03/abstractions-in-mathematics/">Hunting for abstractions in mathematics</a>: Jedem Softwareentwickler ist Abstraktion geläufig, aber wie abstrakt arbeiten Softwareentwickler wirklich? Ohne behaupten zu wollen, dass Abstraktion immer die richtige Lösung darstellt, kann man betrachten, wie abstrakt die Mathematiker arbeiten.</li><li><a href="http://reprog.wordpress.com/2010/03/21/the-hacker-the-architect-and-the-superhero-three-completely-different-ways-to-be-an-excellent-programmer/">The hacker, the architect and the superhero: three completely different ways to be an excellent programmer</a>: Nach Mike Taylor gibt es drei Arten von exzellenten Programmierern - jeder dieser Typen ist mit einer anderen besonderen Fertigkeit ausgestattet. Dieser Artikel kann dabei helfen, seine eigenen Stärken zu erkennen und daraus Konsequenzen zu ziehen.</li><li><a href="http://www.golem.de/1003/74014.html">Tikanga, Pachika und Javalanche helfen bei der Fehlersuche </a>: <a href="http://www.golem.de/">Golem.de</a> hat eine schöne Zusammenfassung von drei wichtigen Projekten des Teams um <a href="http://www.st.cs.uni-saarland.de/zeller/">Andreas Zeller</a> erstellt. Bei allen drei Projekten geht es um Fehler: Wie man sie vermeidet, wie man sie (automatisiert) repariert und wie man Tests optimiert, sodass sie möglichst viele Fehler erkennen.</li><li><a href="http://blog.couch.io/post/468392274/whats-new-in-apache-couchdb-0-11-part-three-new">What’s new in Apache CouchDB 0.11 — Part Three: New Features in Replication</a>: Jan Lehnardt schreibt über eines der wichtigsten Features von CouchDB: Der Replikation. Auf einige Erklärungen zum Mechanismus folgt eine Reihe von interessanten Anwendungsfällen.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Thu, 01 Apr 2010 09:07:00 +0200</pubDate>
            <category>algorithmen</category>
            <category>haskell</category>
            <category>links</category>
            <category>php</category>
            <category>softwaretechnik</category>
            <category>theorie</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-maerz-2010</guid>
            <title>Linktipps März 2010</title>
            <link>http://blackflash.nordic-dev.de/linktipps-maerz-2010</link>
            <description><![CDATA[<ul>
<li><a href="http://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/">Haskell Antipattern: Existential Typeclass</a>: Wie in jeder Sprache gibt es auch in Haskell <a href="http://de.wikipedia.org/wiki/Anti-Pattern">Antimuster</a>, wie Luke Palmer am Beispiel von existentiellen Typklassen zeigt.</li><li><a href="http://developers.facebook.com/news.php?blog=1&story=358">HipHop for PHP: Move Fast</a>: Facebooks Ankündigung eines Produkts, mit dessen Hilfe man PHP-Code in (schnelleren) C++-Code transformieren kann.</li><li><a href="http://terrychay.com/article/hiphop-for-faster-php.shtml">Faster PHP fo shizzle—HipHop for PHP</a>: Terry Chay präsentiert den wahrscheinlich ausführlichsten Artikel über HipHop for PHP, der zudem noch mit vielen interessanten Fakten über Facebook gespickt ist.</li><li><a href="http://apfelmus.nfshost.com/articles/operational-monad.html">The Operational Monad Tutorial</a>: Heinrich Apfelmus erklärt Monaden aus operationaler Sicht, so wie man es von ihm gewohnt ist: Profund, exakt und verständlich.</li><li><a href="http://techportal.ibuildings.com/2010/02/08/coding-is-the-easy-part/">Coding Is The Easy Part</a>: Man sollte sich stets daran erinnern, dass Softwareentwicklung nicht nur aus Programmieren besteht. DIeser Artikel hilft dabei, denn er erklärt jede wesentliche Rolle im Lebenszyklus der Software.</li><li><a href="http://www.heise.de/developer/artikel/Episode-17-Einstieg-in-REST-921652.html">Episode 17: Einstieg in REST</a>: Der heise Developer SoftwareArchitekTOUR-Podcast gibt eine hörenswerte Einführung in die REST-Welt.</li><li><a href="http://www.mikealrogers.com/archives/726">ch-ch-ch-changes!</a>: Auch CouchDB kennt <a href="http://de.wikipedia.org/wiki/Observer_%28Entwurfsmuster%29">Beobachter</a> - und schon wird Comet trivial.</li><li><a href="http://www.drdobbs.com/architect/217701907">Software Engineering &#8800; Computer Science</a>: Chuck Connell schreibt über die Unterschiede zwischen Softwaretechnik und (mathematische) Informatik und zieht interessante Schlüsse. Sehr lesenswert für jeden, der mit beiden Themen hantiert. In diesem Sinne ist auch ein <a href="http://www.se-radio.net/podcast/2009-11/episode-149-difference-between-software-engineering-and-computer-science-chuck-conne">SE-Radion Podcast mit Chuck Connel</a> hörenswert.</li><li><a href="http://horicky.blogspot.com/2010/02/nosql-graphdb.html">NoSQL GraphDB</a>: Wer sich für die NoSQL und Graphentheorie interessiert, wird sich sicherlich auch für die Kombination derselben interessieren: Graphendatenbanken. Ricky Ho beschreibt ihre grundlegende Funktionsweise.</li><li><a href="http://www.kingcrunch.de/blog/2010/02/12/links-git/">Gesammelte Links: Git</a>: KingCrunch hat zahl- und hilfreiche Links gesammelt, die mir den Einstieg in github erleichtert haben - sehr empfehlenswert.</li><li><a href="http://www.cheat-sheets.org/">Cheat-Sheets.org</a>: Fans von Cheat-Sheets werden an dieser Webseite ihre Freude haben.</li><li><a href="http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html">Testing Code That Uses Singletons</a>: Sebastian Bergmann hat schön auf den Punkt gebracht, weshalb man Singletons nicht verwenden sollte - auch wenn es ein sog. Entwurfsmuster ist.</li><li><a href="http://paczesiowa.blogspot.com/2010/01/pure-extensible-exceptions-and-self.html">Pure, extensible exceptions and self-returning functions</a>: Auch wenn ich nur die Hälfte des Artikels verstanden habe, erscheint er mir ziemlich wertvoll, da er nicht nur gut geschrieben ist, sondern auch einen neuen Ansatz für Exceptions, wie er bisher nicht möglich war, einführt. </li><li><a href="http://ralphschindler.com/2010/02/18/the-anatomy-of-a-bug-issue-reproduction-script">The Anatomy Of A Bug/Issue Reproduction Script</a>: Dieser Artikel ist ein Muss für jeden, der ein Open-Source-Projekt durch einen Bug-Report unterstützen will. Wenn man bereits die fünf genannten Punkte, auf die es ankommt, beherzigt, dann hilft man dem entsprechenden Entwickler enorm weiter!</li><li><a href="http://www.heise.de/developer/artikel/Episode-18-Anti-Patterns-und-Tools-fuer-REST-924171.html">Episode 18: (Anti-)Patterns und Tools für REST</a>: Wie die Einführung ein sehr schöner Podcast zum Thema REST. Vor allem die Patterns bzw. Anti-Patterns sind sehr interessant.</li><li><a href="http://blog.astrumfutura.com/archives/421-PHP-Framework-Benchmarks-Entertaining-But-Ultimately-Useless.html">PHP Framework Benchmarks: Entertaining But Ultimately Useless</a>: "Traue keiner Statistik, die du nicht selbst gefälscht hast." Dies trifft auch auf Benchmarks zu, wie dieser unterhaltsame Artikel beweist.</li><li><a href="http://techportal.ibuildings.com/2010/02/22/scaling-web-applications-with-hmvc/">Scaling Web Applications with HMVC</a>: Hierbei geht es um das Hierarchische Model-View-Controller-Muster, das es spätestens seit 2000 gibt, aber von dem ich erst heute gehört habe. Jedenfalls sieht das HMVC-Muster sauberer aus, wobei daraus auch Vorteile, wie gute Skalibarkeit, folgen können.</li><li><a href="http://www.iis.sinica.edu.tw/%7Escm/2010/a-survey-of-binary-search/">A Survey of Binary Search</a>: Shin-Cheng Mu beschreibt, wie man das Konzept der binären Suche mithilfe einer Relation aufbauen kann. Mithilfe einer solchen Relation und einem Algorithmus, der bewiesenermaßen (via Hoare-Kalkül) einige Eigenschaften besitzt, kann man anschließend verschiedene Probleme mit demselben Algorithmus lösen.</li><li><a href="http://pchiusano.blogspot.com/2010/01/actors-are-not-good-concurrency-model.html">Actors are not a good concurrency model</a>: Warum das vielgelobte <a href="http://en.wikipedia.org/wiki/Actor_model">Actor-Modell</a> auch Schwächen hat, wird in diesem Artikel erörtert. Auch die kritischen Kommentare sind sehr lesenswert.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sun, 28 Feb 2010 23:54:00 +0100</pubDate>
            <category>couchdb</category>
            <category>datenbanken</category>
            <category>haskell</category>
            <category>links</category>
            <category>php</category>
            <category>softwaretechnik</category>
            <category>theorie</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/currying-in-php</guid>
            <title>Currying in PHP</title>
            <link>http://blackflash.nordic-dev.de/currying-in-php</link>
            <description><![CDATA[<p>Mithilfe vom Currying (benannt nach Haskell Brooks Curry) kann man eine n-stellige Funktion in n einstellige Funktionen umwandeln. Da PHP keine funktionale Programmiersprache ist, wird dieses Verfahren zwar nicht unterstützt, aber mithilfe der Closures aus PHP 5.3 lässt sich eine Funktion <em>curry</em> entwickeln, die das Currying-Verfahren auf PHP überträgt. Bevor ich zur Implementierung komme, möchte ich Currying anhand von Haskell beschreiben. Wir beginnen bei einem trivialen Beispiel: Der Multiplikation.</p>
<code name="code" class="haskell">
(*) :: (Num a) =&gt; a -&gt; a -&gt; a
(4*) :: (Num a) =&gt; a -&gt; a
(4*2) :: (Num a) =&gt; a
</code>
<p>An den Typen der Ausdrücke <em>(*)</em>, <em>(4*)</em> und <em>(4*2)</em> kann man bereits den Einsatz von Currying erkennen, wenn man weiß, dass die Klammerung bei Typsignaturen rechtsassoziativ ist. Schreiben wir diese Klammern explizit hin, ist der Typ von <em>(*)</em> nämlich <em>(a -&gt; (a -&gt; a))</em>. Wenn man die Grundlagen funktionaler Programmierung beherrscht, kann man daraus ablesen, dass <em>(*)</em> ein Argument nimmt und eine Funktion vom Typ <em>(a -&gt; a)</em> zurückgibt. Wenn man der zurückgegebenen Funktion ein weiteres Argument gibt, bekommt man eine null-stellige Funktion vom Typ <em>a</em> zurück. In Haskell geschieht dieses Currying und die damit verbundene partielle Anwendung von Funktionen transparent, sodass man diesem Umstand meist nicht gewahr ist.
</p>
<p>
Im Grunde genommen soll es also nur stets einstellige Funktionen geben, die entweder eine weitere einstellige Funktion oder das Ergebnis zurückgeben. Das Multiplikationsbeispiel könnte man in PHP folgendermaßen beschreiben:
</p>
<code name="code" class="php">
$mult = function($x) {
	return function ($y) use ($x) {
		return $x*$y;
	};
};
$f = $mult(4);
$g = $f(2);
</code>
<p><em>$mult</em> ist hierbei eine einstellige-Funktion, die eine weitere einstellige Funktion zurückliefert. <em>$mult(4) = $f</em> ist eine solche einstellige Funktion, die ihr Argument mit <em>4</em> multipliziert und das Ergebnis <em>$f(2) = $g = 8</em> zurückliefert. Die Art und Weise, mit der die zwei-stellige Multiplikation in eine gecurryte Funktion umgewandeln wurde, kann man für beliebige <em>n</em> adaptieren, wie folgender Code zeigt:</p>
<code name="code" class="php">
function curry($f, array $args = array()) {
	$refl = new ReflectionFunction($f);
	$n = $refl-&gt;getNumberOfParameters();
	
	if($n &lt;= 1) {
		return $f;
	}
	if(count($args) == $n-1) {
		return function ($x) use ($f, $args) {
			$args[] = $x;
			return call_user_func_array($f, $args);
		};
	}
	
	return function ($x) use ($f, $args) {
		$args[] = $x;
		return curry($f, $args);
	};
}
</code>
<p>Hierbei wird großer Nutzen von Closures und der Reflection-API gemacht. Insgesamt spiegelt der Algorithmus die Idee, wie ich sie bereits beschrieben habe, wieder. Die notwendigen Anpassungen, damit man die Idee in PHP ausdrücken kann, sind rein technischer Natur. Allerdings haben solche gecurryte Funktionen einen Nachteil: Man kann nicht mehrere Argumente zugleich auswerten. Denkbar wären folgende Varianten:</p>
<code name="code" class="php">
$mult(4)(2); // funktioniert nicht
$mult(4,2); // funktioniert auch nicht, wäre aber denkbar
// eigene:
function call($f) {
	return array_reduce(
		array_slice(func_get_args(), 1),
		function ($f, $p) { return $f($p); },
		$f
	);
}
call($mult, 4, 2);
</code>
<p>Während die erste Variante durch die PHP-Syntax nicht ermöglicht wird, wäre die zweite Variante eine denkbare Alternative, die allerdings einige Spezialfälle einführen würde. Eine eigene Funktion zur Auswertung mehrere Argumente ist jedoch auch sehr schnell implementiert und zugleich verständlich.</p>
<p>Da es sich bei diesen Funktionen um Ideen aus der funktionalen Programmierung handelt, habe ich einen eigenen Ordner <a href="http://github.com/Blackflash/nordic-development/tree/master/PHP/PhP/">PhP</a>, der für Phunctional Programming steht, in einem <a href="http://github.com/Blackflash/nordic-development">Github-Repository</a> eingeführt, wo sich im Laufe der Zeit weitere solche Funktionen ansammeln werden.</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 20 Feb 2010 14:02:00 +0100</pubDate>
            <category>algorithmen</category>
            <category>php</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/komponierbarkeit-mit-bedarfsauswertung</guid>
            <title>Komponierbarkeit mit Bedarfsauswertung</title>
            <link>http://blackflash.nordic-dev.de/komponierbarkeit-mit-bedarfsauswertung</link>
            <description><![CDATA[<p>Heute soll es um eine Eigenschaft gehen, die in einigen funktionalen Programmiersprachen helfen, die Funktionen höchst wiederverwendbar zu gestalten - ohne immense Einbußen in der Geschwindigkeit hinnehmen zu müssen. Es handelt sich dabei um die <a href="http://de.wikipedia.org/wiki/Bedarfsauswertung">Bedarfsauswertung</a> (engl. lazy evaluation) Inspiriert hat mich hierbei der Artikel <a href="http://schlitt.info/opensource/blog/0718_heap_heap_hooray.html">Heap, heap, hooray!</a> von Tobias Schlitt, der folgendes Problem in PHP löst: <em>Gib mir die k kleinsten Elemente aus einem Stream</em>. Durch Haskells Bedarfsauswertung kann ich vom Stream abstrahieren und das Problem als Liste auffassen. Das Problem heißt dann: <em>Gib mir die k kleinsten Elemente einer Liste</em>. Hierfür werde ich den naiven Ansatz verwenden und zeigen, dass Naivität in Haskell nicht immer bestraft wird.</p><p>Der Code besteht aus den Standardfunktionen <em>take</em> und <em>partition</em> sowie aus einem selbstimplementierten Quicksort. Für das Verständnis habe ich die (interne) Implementierung der beiden Funktionen und eine Eigenschaft von <em>partition</em> angegeben.
</p>
<code name="code" class="haskell">
take n _ | n &lt;= 0 = []
take _ []  = []
take n (x:xs)  = x : take (n-1) xs

-- partition satisfies: partition p xs == (filter p xs, filter (not . p) xs)
partition p xs = foldr (select p) ([],[]) xs

qsort [] = []
qsort (x:xs) = qsort smaller ++ [x] ++ qsort greater
 where (smaller,greater) = partition (&lt;= x) xs

bottom k = take k . qsort
</code>
<p>Anhand dieser Funktionen lässt sich eine Auswertungsreihenfolge finden, mit der man die drei kleinsten Elemente der Liste [8,2,1,17,18,12,4,13,5,20,10,11,14,15,19,3,6,7,16,9] ermitteln kann. <br>
</p>
<code>
bottom 3 [8,2,1,17,18,12,4,13,5,20,10,11,14,15,19,3,6,7,16,9]
~&gt; { Def. bottom }
take 3 . qsort $ [8,2,1,17,18,12,4,13,5,20,10,11,14,15,19,3,6,7,16,9]
~&gt; { Def. $ }
take 3 $ qsort [8,2,1,17,18,12,4,13,5,20,10,11,14,15,19,3,6,7,16,9]
~&gt; { Def. qsort }
take 3 $ qsort smaller ++ [8] ++ qsort greater
~&gt; { smaller auswerten }
take 3 $ qsort [2,1,4,5,3,6,7] ++ ...
~&gt; { Def. qsort }
take 3 $ qsort smaller ++ [2] ++ qsort greater ++ ...
~&gt; { smaller auswerten }
take 3 $ qsort [1] ++ [2] ++ qsort greater ++ ...
~&gt; { Def. qsort }
take 3 $ qsort [] ++ [1] ++ qsort [] ++ [2] ++ qsort greater ++ ...
~&gt; { Def. qsort }
take 3 $ [] ++ [1] ++ [] ++ [2] ++ qsort greater ++ ...
~&gt; { ++ anwenden }
take 3 $ [1,2] ++ qsort greater ++ ...
~&gt; { take solange anwenden wie möglich }
1:2:(take 1 $ qsort greater ++ ...)
~&gt; { greater auswerten }
1:2:(take 1 $ qsort [4,5,3,6,7] ++ ...)
~&gt; { Def. qsort }
1:2:(take 1 $ qsort smaller ++ [4] ++ qsort greater ++ ...)
~&gt; { smaller auswerten }
1:2:(take 1 $ qsort [3] ++ ...)
~&gt; { Def. qsort }
1:2:(take 1 $ qsort [] ++ [3] ++ qsort [] ++ ...)
~&gt; { Def. qsort }
1:2:(take 1 $ [] ++ [3] ++ [] ++ ...)
~&gt; { ++ anwenden }
1:2:(take 1 $ [3] ++ ...)
~&gt; { Def. take }
1:2:3:(take 0 $ ...)
~&gt; { Def. take }
1:2:3:[]
~&gt; { Listenkonstruktor }
[1,2,3]
</code>
<p>Die Variablen <em>smaller</em> bzw. <em>greater</em> werden erst ausgewertet, wenn sie wirklich benötigt werden, d.h. konkret wurden nur die ersten drei Elemente der Liste sortiert - und nicht die gesamte Liste. Wenn die Anzahl der gesuchten Elemente deutlich kleiner als die Liste, spart man (im Allgemeinen) deutlich mehr Zeit, als man bei einem naiven Ansatz erwarten würde.</p><p>Nichtsdestotrotz kann dieser Code nicht mit einer imperativen Implementierung, die für einen bestimmten Einsatz konzipiert wurde, mithalten. Dafür sind Funktionen durch die Bedarfsauswertung besser komponierbar mit verhältnismäßig kleinen Geschwindigkeitseinbußen.</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Tue, 09 Feb 2010 18:26:00 +0100</pubDate>
            <category>algorithmen</category>
            <category>haskell</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-februar-2010</guid>
            <title>Linktipps Februar 2010</title>
            <link>http://blackflash.nordic-dev.de/linktipps-februar-2010</link>
            <description><![CDATA[<ul>
<li><a href="http://paul-m-jones.com/?p=1182">PHP Is Like A Handgun?</a>: Paul M. Jones zitiert eine interessante Analogie.</li><li><a href="http://scienceblogs.com/goodmath/2009/12/academia_vs_industry_an_update.php">Academia vs Industry: an Updated Opinion</a>: MarkCC von <a href="http://scienceblogs.com/goodmath/">Good Math, Bad Math</a> schreibt über seine Erfahrung und Ansichten über die Forschung in Industrie und akademischen Instituten.</li><li><a href="http://neilmitchell.blogspot.com/2010/01/haskell-io-without-monads.html">Explaining Haskell IO without Monads</a>: Ein schönes Tutorial zum Umgang mit IO in Haskell - ohne das Konzept von Monaden erklärt zu haben.</li><li><a href="http://till.klampaeckel.de/blog/archives/80-Wieso-zum-Teufel-benutzt-DU-keine-Versionskontrolle.html">Wieso zum Teufel benutzt DU keine Versionskontrolle?</a>: Eigentlich sollte das eine Frage sein, die sich heutzutage erübrigt haben müsste... Die Erfahrung lehrt etwas anderes.</li><li><a href="http://conal.net/blog/posts/is-program-proving-viable-and-useful/">Is program proving viable and useful?</a>: Trotz der fehlenden, klaren Antwort auf diese Frage, gibt Conal Elliott einige Anregungen zum Nachdenken.</li><li><a href="http://www.brandonsavage.net/build-systems-relevancy-of-automated-builds-in-a-web-world/">Build Systems: Relevancy of Automated Builds In A Web World</a>: Wozu benötigt man einen automatisierten <a href="http://de.wikipedia.org/wiki/Build-System">Erstellungsprozess</a>? Brandon Savage legt seine Gründe zu diesem Thema anhand seiner Erfahrungen dar.</li><li><a href="http://conal.net/blog/posts/can-functional-programming-be-liberated-from-the-von-neumann-paradigm/">Can functional programming be liberated from the von Neumann paradigm?</a>: Conal Elliott propagiert einen neuen Ansatz für funktionale Programmierung: Das Auslagern von I/O-Operationen aus dem Programmierungsmodell. Aber auch viele weitere interessanten Gedanken sind in seinem Artikel enthalten.</li><li><a href="http://www.research.ibm.com/trl/people/mich/pub/200901_popl2009phpsem.pdf">Copy-on-Write in the PHP Language</a>: Dieses Paper behandelt die Semantik von PHP in formaler Weise.</li><li><a href="http://geekcloud.org/2010/01/02/dependency-injection-frameworks-fuer-php/">Dependency Injection Frameworks für PHP</a>: Ein gelungener Überblick über die gängigsten Dependency Injection-Frameworks in PHP.</li><li><a href="http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html">Do not use PHP references</a>: Diese Klarstellung zum Thema Referenzen in PHP sollte für jeden ernsthaften PHP-Entwickler Pflicht sein.</li><li><a href="http://scienceblogs.com/goodmath/2010/01/zippers_making_functional_upda.php">Zippers: Making Functional "Updates" Efficient</a>: Ein sehr hilfreicher Artikel zu einer sehr hilfreichen Datenstruktur funktionaler Programmiersprachen.</li><li><a href="http://www.dcs-media.com/Archive/20-20-top-20-programming-lessons-ive-learned-in-20-years-FH">Top 20 Programming Lessons I've Learned in 20 Years</a>: Wertvolle Tipps für die persönliche Weiterentwicklung rund ums Thema Programmieren.</li><li><a href="http://www.catamorphism.net/">Functional Programming Bibliography</a>: Dieses Projekt wurde erst vor Kurzem gestartet und enthält schon eine ansehnliche Menge an Papers, die sich mit funktionaler Programmierung beschäftigen.</li><li><a href="http://www.wissenschaft-online.de/artikel/1019760">Schleimiger Streckenplaner</a>: Einzeller vs. Ingenieur. Ein Duell mit einem überraschenden Ergebnis.</li><li><a href="http://www.spiegel.de/netzwelt/web/0,1518,673441,00.html">Was ein sicheres Passwort ist</a>: Dieser Artikel sollte für jeden ernsthaften Internetanwender ein Muss sein!</li><li><a href="http://www.davispj.com/2010/01/18/fighting-hype-with-hype.html">Fighting Hype with Hype</a>: Eine sachkundige Antwort auf Ryan Parks <a href="http://www.ryanpark.org/2008/04/top-10-avoid-the-simpledb-hype.html">Top 10 Reasons to Avoid the SimpleDB Hype</a>, welche die Problematik von NOSQL vs. SQL beleuchtet. Vor allem das Fazit sollte man sich zu Herzen nehmen.</li><li><a href="http://netsuperbrain.com/blog/posts/best-haskell-papers-of-2009/">Best Haskell Papers of 2009</a>: Eine zugegebenermaßen subjektiv zusammengestellte Liste der besten Haskell-Papers 2009. Dennoch klingen die meisten beworbenen Paper sehr interessant.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Mon, 01 Feb 2010 12:17:00 +0100</pubDate>
            <category>datenbanken</category>
            <category>haskell</category>
            <category>links</category>
            <category>php</category>
            <category>softwaretechnik</category>
            <category>theorie</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/fibonacci-folge-in-haskell</guid>
            <title>Fibonacci-Folge in Haskell</title>
            <link>http://blackflash.nordic-dev.de/fibonacci-folge-in-haskell</link>
            <description><![CDATA[<p>Heute soll es um die bekannte <a href="http://de.wikipedia.org/wiki/Fibonacci-Folge">Fibonacci-Folge</a> gehen. Dabei werde ich, um mich wieder in funktionale Programmierung zu vertiefen, zwei in Haskell geschriebene Versionen der Fibonacci-Folge angeben und deren Äquivalenz zeigen.</p><p>Die naive Implementierung könnte folgendermaßen aussehen:</p>

<code name="code" class="haskell">
fib n
 | n &lt; 0 = error "n must be greater or equal zero"
 | n == 0 = 0
 | n == 1 = 1
 | n &gt;= 2 = fib (n-1) + fib (n-2)
</code>

<p>Am Beispiel bei <em>n = 6</em> kann man bereits erkennen, weshalb diese Implementierung langsam ist:</p>

<code>
fib 6 = fib 5 + fib 4
~&gt; { fib 5 einsetzen }
fib 6 = fib 4 + fib 4 + fib 3
~&gt; { fib 4 einsetzen }
fib 6 = fib 3 + fib 3 + fib 3 + fib 2 + fib 2
~&gt; { fib 3 einsetzen }
fib 6 = fib 2 + fib 2 + fib 2 + fib 2 + fib 2 + fib 1 + fib 1 + fib 1
~&gt; { fib 2 einsetzen }
fib 6 = fib 1 + fib 1 + fib 1 + fib 1 + fib 1 + fib 1 + fib 1 + fib 1 + fib 0 + fib 0
~&gt; { fib 1 einsetzen }
fib 6 = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + fib 0 + fib 0
~&gt; { fib 0 einsetzen }
fib 6 = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1
~&gt; { + einsetzen }
fib 6 = 8
</code>

<p>Es finden also mehrfache Berechnungen desselben Werts statt. Durch genaueres Hinsehen stellt man folgende Korrelation fest:</p><ul><li>fib 6 wird einmal (fib 1) berechnet.</li><li>fib 5 wird einmal (fib 2) berechnet.</li><li>fib 4 wird zweimal (fib 3) berechnet.</li><li>fib 3 wird dreimal (fib 4) berechnet.</li><li>fib 2 wird fünfmal (fib 5) berechnet.</li><li>fib 1 wird achtmal (fib 6) berechnet.</li></ul><p>D.h. das Ergebnis von <em>fib n</em> ist die Summe von <em>fib n</em> Einsen. Für n = 100 würde das bedeuten, dass man 354.224.848.179.261.915.075 Einsen summiert. Eine effizientere Variante, die Haskells <a href="http://de.wikipedia.org/wiki/Lazy_Evaluation">lazy evaluation</a> ausnutzt, stellt folgende Definition dar.</p>
<code name="code" class="haskell">
fib' = let fibs = [0,1] ++ zipWith (+) fibs (tail fibs) in (fibs !!)
</code>

<p>Der Vorteil an dieser Variante ist, dass jedes Element genau einmal berechnet und anschließend weiterverwendet wird. Aber bevor ich die Äquivalenz zeige, möchte ich noch die wesentlichen verwendeten Funktionen einführen. Beginnen wir bei der Funktion <em>(++)</em>, sprich der Verkettung von zwei Listen, d.h. für zwei beliebige Listen <em>[x<sub>1</sub>, ..., x<sub>n</sub>]</em> und <em>[y<sub>1</sub>, ..., y<sub>m</sub>]</em> gilt <em>[x<sub>1</sub>, ..., x<sub>n</sub>]</em> ++ <em>[y<sub>1</sub>, ..., y<sub>m</sub>] = </em><em>[x<sub>1</sub>, ..., x<sub>n</sub>, y<sub>1</sub>, ..., y<sub>m</sub>]</em>. Mittels <em>xs !! i</em> kann man das <em>i</em>-te (beginnend bei Null) Element aus der Liste <em>xs</em> entnehmen. Die anderen beiden wesentlichen Funktionen <em>tail</em> und <em>zipWith</em> werde ich anhand von Haskell-Code definieren.</p>
<code name="code" class="haskell">
tail [] = error "empty list"
tail (_:xs) = xs

zipWith _ [] _ = []
zipWith _ _ [] = []
zipWith f (x:xs) (y:ys) = (x `f` y) : zipWith f xs ys
</code>

<p><strong>Satz.</strong> fib und fib' sind äquivalent.</p>
<p><strong>Beweis.</strong> Da <em>fib' n</em> jeweils das <em>n</em>-te Element aus der Liste <em>fibs</em> entnimmt, genügt es zu zeigen, dass <em>fibs</em> die Fibonacci-Folge darstellt, d.h. <em>fibs = [fib 0, fib 1, fib 2, ...]</em>. Dass <em>fibs !! 0 = 0 = fib 0</em> und <em>fibs !! 1 = 1 = fib 1</em> gelten, ist offensichtlich. Da <em>fibs</em> die Verkettung von <em>[fib 0, fib 1]</em> und einer Liste, die mittels <em>zipWith</em> erstellt wird, darstellt, muss lediglich gezeigt werden, dass <em>zipWith (+) fibs (tails fibs)</em> und <em>[fib 2, fib 3, ...]</em> äquivalent sind. Nach Definition von <em>zipWith</em> entnimmt selbige jeweils das erste Element aus den beiden übergebenen Listen und berechnet anhand der übergebenen Funktion ein neues Element. D.h. ein <em>i</em>-maliges Anwenden der <em>zipWith</em>-Funktion erzeugt <em>i</em> Elemente, was wiederum bedeutet, dass man durch <em>i</em>-maliges Anwenden von <em>zipWith</em> den Wert von <em>fib (1+i)</em> berechnet. Diese Eigenschaft lässt sich induktiv beweisen.</p>
<p><em>Induktionsanfang</em>. Sei <em>i = 1</em>, dann lässt sich <em>fib (1+i) = fib 2</em> folgendermaßen berechnen:</p>
<code>fibs =[fib 0, fib 1] ++ zipWith (+) fibs (tail fibs)
~&gt; { Def. von fibs }
= [fib 0, fib 1] ++ zipWith (+) [fib 0, fib 1, ...] (tail [fib 0, fib 1, ...])
~&gt; { Def. von tail }
= [fib 0, fib 1] ++ zipWith (+) [fib 0, fib 1, ...] [fib 1, ...]
~&gt; { Def. von zipWith }
= [fib 0, fib 1] ++ (fib 0 + fib 1) : zipWith (+) [fib 1, ...] [...]
~&gt; { Def. von Fibonacci-Folge }
= [fib 0, fib 1] ++ (fib 2) : zipWith (+) [fib 1, ...] [...]
~&gt; { Verkettung }
= [fib 0, fib 1, fib 2] : zipWith (+) [fib 1, ...] [...]</code>

<p><em>Induktionsschritt</em>. Sei <em>zipWith</em> bereits <em>i</em>-mal angewendet worden, d.h. es sind bereits die ersten <em>i+2</em> Werte von <em>fib</em>s bekannt, d.h. <em>take (i+2) fibs = [fib 0, fib 1, ..., fib (i+1)]</em>. Es ist zu zeigen, dass durch eine weitere Anwendung der Wert von <em>fib (1+i+1) = fib (2+i)</em> berechnet wird. Folgender Code illustriert dann die Berechnung für <em>fib (2+i)</em>:</p>

<code>fibs = [fib 0, fib 1] ++ zipWith (+) fibs (tail fibs)
~&gt; { i-maliges Anwenden von zipWith auf fibs }
= [fib 0, fib 1, ..., fib (1+i)] ++ zipWith (+) [fib i, fib (1+i), ...] (tail [fib i, fib (1+i), ...])
~&gt; { Def. von tail }
= [fib 0, fib 1, ..., fib (1+i)] ++ zipWith (+) [fib i, fib (1+i), ...] [fib (1+i), ...]
~&gt; { Def. von zipWith }
= [fib 0, fib 1, ..., fib (1+i)] ++ ((fib i) + fib (1+i)) : zipWith (+) [fib (1+i), ...] [...]
~&gt; { Def. von Fibonacci-Folge }
= [fib 0, fib 1, ..., fib (1+i)] ++ (fib (2+i)) : zipWith (+) [fib (1+i), ...] [...]
~&gt; { Verkettung }
= [fib 0, fib 1, ..., fib (1+i), fib (2+i)] ++ zipWith (+) [fib (1+i), ...] [...]
</code>

<p>Der letzte Fall, der noch gezeigt werden muss, besteht im Fehlerfall. Denn, wenn eine Funktion einen Fehler liefert, soll die andere Funktion mit derselben Eingabe auch einen Fehler liefern. Die Funktion <em>(!!)</em> liefert einen Fehler, wenn entweder der Index zu groß ist oder wenn er negativ ist. Zu groß kann er nicht werden, da es sich bei <em>fibs</em> um eine unendlich lange Liste handelt. D.h. <em>fib' n</em> liefert genau dann einen Fehler, wenn <em>n</em> negativ ist. Da <em>fib n</em> auch nur bei negativen <em>n</em> einen Fehler liefert, sind <em>fib' n</em> und <em>fib n</em> auch für ungültige Eingaben äquivalent.</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Wed, 27 Jan 2010 13:57:00 +0100</pubDate>
            <category>haskell</category>
            <category>theorie</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-januar-2010</guid>
            <title>Linktipps Januar 2010</title>
            <link>http://blackflash.nordic-dev.de/linktipps-januar-2010</link>
            <description><![CDATA[<ul>
<li><a target="_new" href="http://fabien.potencier.org/article/34/templating-engines-in-php">Templating Engines in PHP</a>: Fabien Potencier erläutert in dem Artikel den Status Quo von Template-Engines in PHP. Auch die <a target="_new" href="http://eliw.wordpress.com/2009/10/07/in-response-to-fabien-potencier-twig-php-templating/">Antwort von Eli</a> und der <a target="_new" href="http://fabien.potencier.org/article/35/templating-engines-in-php-follow-up">weiterführende Artikel von Fabien</a> sind des Lesens wert.</li><li><a target="_new" href="http://blog.echolibre.com/2009/10/how-to-build-an-api-in-5-minutes/">How to build an API in 5 minutes</a>: Im verlinkten Video wird erklärt, wie man innerhalb von fünf Minuten eine kleine RESTful-Applikation schreibt. Der Ansatz hat in meinen Augen sehr großes Potential.</li><li><a target="_new" href="http://donsbot.wordpress.com/2009/10/11/self-optimizing-data-structures-using-types-to-make-lists-faster/">Self-optimizing data structures: using types to make lists faster</a>: Don Stewart beschreibt in seinem Blog eine Möglichkeit, wie man Listenoperationen verschnellern kann. Auch wenn man wenig mit Listen arbeitet, so finde ich es dennoch beeindruckend, wie leicht man solche Tricks benutzen kann.</li><li><a target="_new" href="http://www.brandonsavage.net/micro-optimizations-that-matter/">“Micro” Optimizations That Matter</a>: Brandon Savage beschreibt, wie man mit verhältnismäßig kleinen Änderungen eine große Wirkung erzielen kann.</li><li><a target="_new" href="http://chplib.wordpress.com/2009/10/14/emulating-shared-mutable-variables-with-message-passing-processes/">
Emulating Shared Mutable Variables with Message-Passing Processes</a>: Funktionale Programmierung und Nebenläufigkeit passen zusammen, wie dieser Artikel in eleganter Weise zeigt.</li><li><a target="_new" href="http://www.metabrew.com/article/rewriting-playdar-c-to-erlang-massive-savings/">Rewriting Playdar: C++ to Erlang, massive savings</a>:
Richard Jones, evtl. bekannt von last.fm, schreibt über seine
Erfahrungen beim Rewrite von Playdar in Bezug auf Produktivität von
Erlang, einer funktionalen Programmiersprache.</li><li><a target="_new" href="http://www.golem.de/0910/70585.html">Wie Facebook die Daten von 300 Millionen Nutzern verkraftet</a>: Ein interessanter Golem-Artikel, der aufzeigt, wie Facebook verschiedenste Performance-Probleme gelöst hat. Auch das <a target="_new" href="http://video-jsoe.ucsd.edu/asx/JeffRothschildFacebook.asx">Video</a> mit <a target="_new" href="http://cns.ucsd.edu/lecturearchive09.shtml#Roth">Jeff Rothschild</a> ist empfehlenswert.</li><li><a href="http://westhoffswelt.de/blog/0040_quickhull_introduction_and_php_implementation.html" target="_new">Calculate a convex hull - The QuickHull algorithm</a>:
Jakob Westhoff erklärt in diesem Artikel den QuickHull-Algorithmus auf
eine sehr intuitive Weise. Auch wenn es für mich (bisher) keinen
praktischen Nutzen hat, hat es Spaß gemacht, den Artikel zu lesen.</li><li><a target="_new" href="http://martijn.van.steenbergen.nl/journal/2009/10/18/transforming-polymorphic-values/">Transforming polymorphic values</a>: Martijn van Steenbergen gibt eine ausführliche Erläuterung zum Schreiben einer <a target="_new" href="http://de.wikipedia.org/wiki/Dom%C3%A4nenspezifische_Sprache">DSL</a> zum Berechnen (und Vereinfachen) von Termen. Für jeden Haskell-Programmierer empfehlenswert.</li><li><a target="_new" href="http://horicky.blogspot.com/2009/10/notes-on-memcached.html">Notes on Memcached</a>: In seinen Notizen beschreibt Ricky Ho die Architektur von memcached und folgert daraus die Nutzungsmöglichkeiten desselben.</li><li><a target="_new" href="http://www.brandonsavage.net/adapting-the-joel-test-to-web-development/">Adapting The Joel Test To Web Development</a>:
Brandon Savage erklärt seine Adaption von Joel Spolskys 12-Punkte-Test
für Softwarehersteller. Jeder, der professionell Software entwickelt,
sollte diese zwölf Punkte beherzigen.</li><li><a target="_new" href="http://www.heise.de/developer/artikel/Clean-Code-Developer-in-Brownfield-Projekten-855114.html">Clean Code Developer in Brownfield-Projekten</a>: Der Artikel beschreibt die größten Probleme bei <a href="http://en.wikipedia.org/wiki/Brownfield_%28software_development%29" target="_new">Brownfield-Projekten</a> - auch als Abschreckung geeignet.</li><li><a target="_new" href="http://lukeplant.me.uk/blog/posts/is-static-type-checking-a-redundant-testing-mechanism/">Is static type checking a redundant testing mechanism?</a>:
Luke Plant erläutert einige interessante Feststellungen zu Unit-Tests
sowie statischer Typisierung und deklarativer Programmierung im
Allgemeinen und Haskell im Speziellen.</li><li><a target="_new" href="http://joshua.schachter.org/2007/01/autoincrement.html">autoincrement considered harmful</a>:
Warum ist autoincrement doch nicht das Wahre? Abgesehen davon, dass es
die Nebenläufigkeit erschwert, werden hier drei weitere Gründe
aufgeführt.</li><li><a target="_new" href="http://till.klampaeckel.de/blog/archives/75-PHP-So-youd-like-to-migrate-from-MySQL-to-CouchDB-Part-II.html">PHP: So you'd like to migrate from MySQL to CouchDB? - Part II</a>: Nach dem <a target="_new" href="http://till.klampaeckel.de/blog/archives/74-PHP-So-youd-like-to-migrate-from-MySQL-to-CouchDB-Part-I.html">ersten Teil</a> stellt dieser Artikel eine sehr pragmatische Einführung in CouchDB (mittels PHP) dar.</li><li><a target="_new" href="http://chplib.wordpress.com/2009/11/10/the-observer-pattern-using-a-message-passing-process/">The Observer Pattern using a Message-Passing Process</a>:
Auf dem CHP-Blog findet sich dieses Mal ein Artikel darüber, wie man
das Observer-Entwurfsmuster nebenläufig in Haskell implementieren kann.</li><li><a target="_new" href="http://twan.home.fmf.nl/blog/haskell/four-ways-to-fold.details">Four ways to fold an array</a>:
Neben den geläufigen zwei Faltungen (foldr und foldl) hat Twan van
Laarhoven zwei weitere Faltungen mit Hilfe von Arrays entwickelt.</li><li><a target="_new" href="http://blog.sigfpe.com/2009/10/what-category-do-haskell-types-and.html">"What Category do Haskell Types and Functions Live In?"</a>: Dieser Artikel bringt <a target="_new" href="http://de.wikipedia.org/wiki/Kategorientheorie">Kategorientheorie</a>
und Haskell zusammen. Auch wenn ich nicht alle erwähnten Begriffe
kenne, finde ich ihn vor allem wegen der weiterführenden Links sehr
lesenswert.</li><li><a target="_new" href="http://cdsmith.wordpress.com/2009/11/02/monads-from-two-perspectives/">Monads from Two Perspectives</a>:
Auch dieser Artikel bringt Kategorientheorie und Haskell zusammen, in
dem er Monaden auf mathematische Weise erklärt und den Bezug zu den
Monaden in Haskell erläutert.</li><li><a target="_new" href="http://jan.prima.de/plok/archives/185-NoSQL-Berlin-Debrief.html">NoSQL Berlin Debrief</a>: Auf Jan Lehnardts Blog finden sich Links zu den Präsentationen auf dem NoSQL-Berlin-Event.</li><li><a target="_new" href="http://horicky.blogspot.com/2009/11/amazon-cloud-computing.html">Amazon Cloud Computing</a>: Ricky Ho bietet einen sehr genauen Überblick über die Cloud Services von Amazon.</li><li><a target="_new" href="http://leimy9.blogspot.com/2009/11/long-running-haskell-applications.html">Long running Haskell applications</a>:
Dieser interessante Erfahrungsbericht über Haskell fördert das wohl
häufigste Problem bei Haskellprogrammen zutage: Space Leaks. Die
Wirksamkeit der Lösung wird dabei durch Diagramme untermauert. Weitere
Lösungsmöglichkeit wurden durch die <a target="_new" href="http://thread.gmane.org/gmane.comp.lang.haskell.cafe/66056">weiterführende Diskussion</a> erläutert.</li><li><a target="_new" href="http://blog.sigfpe.com/2009/01/haskell-monoids-and-their-uses.html">Haskell Monoids and their Uses</a>:
sigfpe erklärt auf seinem Blog Monoide und deren Use-Cases. Das ist
wahrscheinlich die ausführlichste Erklärung zu diesem Thema, auf die
ich bisher gestoßen bin.</li><li><a target="_new" href="http://ashish.typepad.com/ashishs_niti/2007/06/haskell_dsl_and.html">Haskell, DSL and Monad</a>: Haskell, DSL und Monaden? Diese Begriffe klingen vielleicht schwierig, aber dieser Artikel zeigt das Gegenteil.</li><li><a target="_new" href="http://horicky.blogspot.com/2009/11/cloud-computing-patterns.html">Cloud Computing Patterns</a>: Ricky Ho stellt verschiedene Muster vor, die man beim Cloud-Computing verwendet.</li><li><a target="_new" href="http://chplib.wordpress.com/2009/11/16/an-introduction-to-communicating-sequential-processes/">An Introduction to Communicating Sequential Processes</a>: Dass Haskell auf dem Lambda-Kalkül aufbaut, ist nicht neu, aber mir war neu, dass <abbr title="Communicating Haskell Processes">CHP</abbr> auf der <a target="_new" href="http://de.wikipedia.org/wiki/Communicating_Sequential_Processes">CSP</a>-Prozessalgebra basiert. Es ist immer wieder interessant zu sehen, wie die Theorie in der Praxis eingesetzt wird.</li><li><a target="_new" href="http://chplib.wordpress.com/2009/11/20/the-operators-and-monoids-of-chp/">The Operators and Monoids of CHP</a>: Auch hier schlägt die Mathematik zu, denn auch Funktionen können wie <a target="_new" href="http://de.wikipedia.org/wiki/Algebraische_Struktur">algebraische Strukturen</a> untersucht werden. Hier wird dies am Beispiel des Monoids getan.</li><li><a target="_new" href="http://neilmitchell.blogspot.com/2009/11/reviewing-view-patterns.html">Reviewing View Patterns</a>: Auf seinem Blog beschreibt <a target="_new" href="http://neilmitchell.blogspot.com/">Neil Mitchell</a> die sog. <a target="_new" href="http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#view-patterns">View-Patterns</a> und schlägt einige Verbesserungen vor. Auch wenn ich die View-Patterns noch nicht verwendet habe, sehen sie sehr hilfreich aus.</li><li><a href="http://horicky.blogspot.com/2009/11/nosql-patterns.html" target="_new">NOSQL Patterns</a>:
Sehr detailliert, sehr interessant, aber auch sehr lang. Wer etwas mehr
über den aktuellen Stand der Technik der NoSQL-Welt erfahren will, ist
mit dem Artikel bestens bedient.</li><li><a target="_new" href="http://www.haskell.org/haskellwiki/What_a_Monad_is_not">What a Monad is not</a>: Der Name sagt bereits alles - besonders für Einsteiger sehr lesenswert.</li><li><a target="_new" href="http://blog.plover.com/prog/burritos.html">Monads are like burritos</a>: Wer sich mit Haskell beschäftigt, kennt evtl. <a target="_new" href="http://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/">Brent Yorgeys Meinung zum Thema Monaden-Tutorials</a> - der Linktipp enthält die Antwort auf diesen Beitrag.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 02 Jan 2010 04:56:00 +0100</pubDate>
            <category>algorithmen</category>
            <category>couchdb</category>
            <category>datenbanken</category>
            <category>haskell</category>
            <category>kategorientheorie</category>
            <category>links</category>
            <category>mathematik</category>
            <category>php</category>
            <category>softwaretechnik</category>
            <category>theorie</category>
            <category>web</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-15</guid>
            <title>Linktipps #15</title>
            <link>http://blackflash.nordic-dev.de/linktipps-15</link>
            <description><![CDATA[<ul>
<li><a href="http://www.vimeo.com/6627041" target="_new">Automatically RESTful Web Applications: Marking Modular Serializable Continuations</a>: Das Video zeigt einen inspirierenden Ansatz für Webprogrammierung.</li><li><a target="_new" href="http://www.sauria.com/blog/2009/10/05/the-cambrian-period-of-concurrency/">The Cambrian Period of Concurrency</a>: Ted Leung gibt einen Überblick verschiedener Concurrency-Konzepte.</li><li><a target="_new" href="http://blog.digitalstruct.com/2009/10/07/deployments-php-applications/">Deployment of PHP Applications</a>: Auch wenn der Titel suggeriert, dass es sich speziell um PHP-Applikationen handelt, kann die beschriebene Vorgehensweise beim Deployment jedes Projekts helfen.</li><li><a target="_new" href="http://horicky.blogspot.com/2009/10/re-engineer-legacy-architecture.html">Re-engineer Legacy Architecture </a>: Wie geht man mit einem Legacy-System um? Ricky Ho erklärt es.</li><li><a target="_new" href="http://cacm.acm.org/magazines/2009/9/38904-the-status-of-the-p-versus-np-problem/fulltext">The Status of the P Versus NP Problem</a>: Der Artikel enthält viele interessante Fakten zum P-NP-Problem - trotz der Länge sehr empfehlenswert.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 26 Dec 2009 11:24:00 +0100</pubDate>
            <category>haskell</category>
            <category>links</category>
            <category>softwaretechnik</category>
            <category>theorie</category>
            <category>web</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-reloaded</guid>
            <title>Linktipps reloaded</title>
            <link>http://blackflash.nordic-dev.de/linktipps-reloaded</link>
            <description><![CDATA[<p>Ich habe mich dazu entschlossen, die Linktipps in anderer Form weiterzuführen. Natürlich möchte ich diesen Schritt auch begründen und meine Pläne zu dieser Reformation darlegen.</p><p>Zuerst möchte ich mein Bedauern ausdrücken, dass sieben der letzten zehn Artikel Linktipps waren. Zwar finde ich die Linktipps weiterhin interessant, aber das rechtfertigt keinen Prozentsatz von 70 Punkten. Deshalb habe ich mich entschlossen, die Linktipps nur noch einmal im Monat zu veröffentlichen. Da ich in den letzten Monaten sehr viele interessante Links gefunden habe, konnte ich einen Vorrat von ca. 30 Links aufbauen. Ein großer Teil davon wird bereits im Januar gepostet. Danach werde ich wahrscheinlich 10-15 Links pro Monat empfehlen.</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Wed, 23 Dec 2009 10:18:00 +0100</pubDate>
            <category>links</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-14</guid>
            <title>Linktipps #14</title>
            <link>http://blackflash.nordic-dev.de/linktipps-14</link>
            <description><![CDATA[<ul>
<li><a target="_new" href="http://www.nytimes.com/2009/09/20/jobs/20pre.html?_r=2&ref=technology">For Writing Software, a Buddy System</a>: Ein sehr schön geschriebener Artikel über Paarprogrammierung von der New York Times.</li><li><a target="_new" href="http://chplib.wordpress.com/2009/09/30/poison-concurrent-termination/">Poison: Concurrent Termination</a>: Wieder ein Artikel des <a target="_new" href="http://chplib.wordpress.com/">CHP-Blogs</a>, der dieses Mal einen simplen, aber effektiven Mechanismus zum sauberen Beenden von parallelen Programmen zum Thema hat.</li><li><a target="_new" href="http://martijn.van.steenbergen.nl/journal/2009/10/02/let-5-6/">let 5 = 6</a>: Ein let-Ausdruck, der 5 = 6 ausdrückt, ist gültig? Der Artikel klärt über das Warum auf.</li><li><a href="http://www.heise.de/developer/Requirements-Engineering-in-Zeiten-der-Agilitaet--/artikel/146145/0" target="_new">Requirements Engineering in Zeiten der Agilität</a>: Dieser heise-developer-Artikel gibt einige Informationen zu agilem Projektmanagement in Bezug auf die Anforderungserhebung.</li><li><a target="_new" href="http://www.youtube.com/watch?v=ESDBM9-U804">CouchDB: Relaxing Offline JavaScript</a>: Ein gelungener Google Tech Talk über die gelungene CouchDB. Zwar geht die Präsentation eine Stunde, aber wer die Zeit hat, der kann sie gut investieren.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 12 Dec 2009 17:28:00 +0100</pubDate>
            <category>couchdb</category>
            <category>haskell</category>
            <category>links</category>
            <category>softwaretechnik</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-13</guid>
            <title>Linktipps #13</title>
            <link>http://blackflash.nordic-dev.de/linktipps-13</link>
            <description><![CDATA[<ul>
<li><a href="http://www.brandonsavage.net/essential-ini-settings/" target="_new">Configuring PHP: Essential INI Settings</a>: Dem erfahrenen PHP-Entwickler werden diese wichtigen Konfigurationsdirektiven bereits ein Begriff sein, aber für Einsteiger ist es eine klare und vor allem kommentiere Übersicht.</li><li><a href="http://blog.liip.ch/archive/2009/09/28/fine-grained-svn-commit-emails-made-easy.html" target="_new">Fine-grained SVN commit emails made easy</a>: Um die Qualität eines (größeren) Projekts zu gewährleisten gibt es viele Möglichkeiten: Dieser Artikel beschreibt eine weitere, die ich durchaus sinnvoll finde.</li><li><a href="http://www.golem.de/0909/70113.html" target="_new">Helios - Microsoft forscht am Betriebssystem der Zukunft</a>: Nachdem ich bereits über <a href="http://blackflash.nordic-dev.de/singularity-wirklich-eine-seltenheit">Singularity</a> gebloggt habe, möchte ich dieses Mal auf ein weiteres Projekt von Microsoft Research verweisen, das ich recht interessant finde. Mir scheint es, als gäbe es bei der Entwicklung von Betriebssystemen zu wenige Innovationen. <a target="_new" href="http://www.golem.de/0909/70153.html">Barrelfish</a> und <a target="_new" href="http://www.golem.de/0902/65437.html">Gazelle</a> sind ähnlich interessante Projekte von Microsoft Research.</li><li><a href="http://www.phphatesme.com/blog/webentwicklung/10-auswahlkriterien-fur-php-frameworks/" target="_new">10 Auswahlkriterien für PHP-Frameworks</a>: Ralf Eggert gibt zehn Tipps, die man bei der Auswahl eines Frameworks beherzigen sollte.</li><li><a href="http://www.serpentine.com/blog/2009/09/29/criterion-a-new-benchmarking-library-for-haskell/" target="_new">Criterion, a new benchmarking library for Haskell</a>: Bryan O’Sullivan, einer der Autoren von Real World Haskell, schreibt über seine Bibliothek zum Benchmark, die mir sehr gelungen erscheint.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sun, 29 Nov 2009 13:54:00 +0100</pubDate>
            <category>betriebssystem</category>
            <category>haskell</category>
            <category>links</category>
            <category>php</category>
            <category>softwaretechnik</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-12</guid>
            <title>Linktipps #12</title>
            <link>http://blackflash.nordic-dev.de/linktipps-12</link>
            <description><![CDATA[<ul>
<li><a target="_new" href="http://anarchycreek.com/2009/05/26/how-tdd-and-pairing-increase-production/">How TDD and Pairing Increase Production</a>: Mit diesem Artikel werden einige Vorurteile über <a target="_new" href="http://de.wikipedia.org/wiki/Testgetriebene_Entwicklung">testgetriebene Entwicklung</a> und <a target="_new" href="http://de.wikipedia.org/wiki/Paarprogrammierung">Paarprogrammierung</a> ausgeräumt.</li><li><a target="_new" href="http://chplib.wordpress.com/2009/09/24/the-expanding-prime-pipeline/">Concurrent Pearl: The Expanding Prime Pipeline</a>: Anhand dieses Artikels wird die Idee eines parallelen Primzahlsiebs erklärt.</li><li><a target="_new" href="http://haskell.org/haskellwiki/User:Michiexile/MATH198">Stanford MATH 198: Category Theory for Functional Programming</a>: Hintergrundmaterial für einen Kurs über Kategorientheorie für funktionale Programmierung.</li><li><a target="_new" href="http://www.joelonsoftware.com/items/2009/09/23.html">The Duct Tape Programmer</a>: Warum ist schlechter manchmal besser? Dieser Artikel klärt über die Frage auf.</li><li><a href="http://www.adaniels.nl/articles/how-i-php-multiple-inheritance/" target="_new">How I PHP: multiple inheritance</a>: Der Autor erklärt einige Varianten, wie man etwas Ähnliches wie Mehrfachvererbung in PHP realisieren kann.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 14 Nov 2009 14:48:00 +0100</pubDate>
            <category>haskell</category>
            <category>links</category>
            <category>mathematik</category>
            <category>php</category>
            <category>softwaretechnik</category>
            <category>theorie</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/meine-firefox-extensions</guid>
            <title>Meine Firefox-Extensions</title>
            <link>http://blackflash.nordic-dev.de/meine-firefox-extensions</link>
            <description><![CDATA[<p>Obwohl ich den Firefox bereits seit langer Zeit und mit großer Intensivität nutze, gehöre ich wahrscheinlich zu denjenigen, die verhältnismäßig wenige Erweiterungen verwenden. Deshalb hier erstmal die Liste, der von mir verwendeten Erweiterungen:</p>
<ol>
<li><a target="_new" href="http://overstimulate.com/projects/taboo">Taboo</a></li><li><a target="_new" href="http://tmp.garyr.net/">Tab Mix Plus</a></li><li><a target="_new" href="http://www.xmarks.com/">Xmarks</a></li><li><a target="_new" href="http://adblockplus.org/en/">Adblock Plus</a></li><li><a target="_new" href="http://www.ghostery.com/">Ghostery</a></li><li><a target="_new" href="http://www.getfiregpg.org/s/home">FireGPG</a></li><li><a target="_new" href="https://addons.mozilla.org/de/firefox/addon/3829">LiveHTTPHeaders</a></li><li><a target="_new" href="http://mattconstantine.com/minimalistgmail">Minimalist Gmail</a></li></ol></li><h3>Taboo</h3>
<p>
Jeder, der viel im Internet surft und auf viele interessante Webseiten stößt, aber meist nicht die Zeit hat, diese sofort zu lesen, wird von dieser Erweiterung begeistert sein. Solche Webseiten lassen sich dann mit einem Klick in einer Liste speichern, auf die man dann später problemlos zugreifen kann. Dadurch kann man Ordnung schaffen, ohne die Unordnung in die Lesezeichen zu verschieben.
</p>

<h3>Tab Mix Plus</h3>
<p>
Mit Tab Mix Plus kann man sehr viele Einstellungen an seinen Tabs vornehmen. Besonders das Öffnen von (versehentlich) geschlossenen Tabs ist bei mir sehr hilfreich.
</p>

<h3>Xmarks</h3>
<p>
Xmarks ist meine neueste Errungenschaft. Damit lassen sich Lesezeichen und ggf. Passwörter mit einem Server synchronisieren. Besitzt man einen eigenen WebDAV-fähigen Server, so kann man Lesezeichen und Passwörter auf dem eigenen Server speichern. Dadurch steigt nicht nur der Komfort, sondern im Allgemeinen auch die Sicherheit, da man nun bei jedem Webdienst sichere und unterschiedliche Passwörter verwenden kann, ohne sie sich merken zu müssen.
</p>

<h3>Adblock Plus</h3>
<p>
Zu Adblock Plus muss wahrscheinlich nicht viel gesagt werden: Weg mit der Werbung!
</p>

<h3>Ghostery</h3>
<p>
Mit Ghostery bekommt man einen Einblick, wie viele Webdienstleister arbeiten: <a href="http://de.wikipedia.org/wiki/Web_Analytics">Web-Analytics</a>, <a href="http://en.wikipedia.org/wiki/Advertising_network">Werbenetzwerke</a> und andere Widgets. Die meisten Webpräsenzen sind alles andere als datenschutzfreundlich, da im Hintergrund Anfragen an externe Webanalytic-Anbieter gesendet werden, von denen die meisten Benutzer nichts wissen. Ein Web-Analytic-Monopolist könnte dann sehr detaillierte Nutzerprofile anhand der besuchten Webseiten erstellen. Glücklicherweise gibt es Ghostery: Man kann solche Anfragen kurzerhand blockieren. Kurz noch in eigener Sache: Ich verwende zwar die Web-Analytic-Software <a href="http://piwik.org/">Piwik</a>, aber die ist auf meinem Server gehostet, sodass nur ich Zugriff auf diese Daten habe. Wer selbst das nicht möchte, darf natürlich auch Piwik mit Ghostery blockieren.
</p>

<h3>FireGPG</h3>
<p>
Mit FireGPG kann man E-Mails ver- und entschlüsseln sowie Signaturen erstellen und verifizieren. Wieder ein Gewinn für die Sicherheit.
</p>

<h3>LiveHTTPHeaders</h3>
<p>
Diese Erweiterung ist für jeden, der mehr über das, was im Hintergrund passiert, erfahren möchte, ist mit dieser Erweiterung gut bedient. Nicht nur für Webentwickler, die das HTTP besser verstehen wollen, sondern auch interessierte Nutzer, die erfahren wollen, welche Daten zu welchem Server gesendet werden, kann diese Erweiterung viele neue Erkenntnisse bringen.
</p>

<h3>Minimalist Gmail</h3>
<p>
Wer mag schon überladene Benutzerschnittstellen? Ich nicht. Selbst beim bereits ziemlich schlanken Gmail lassen sich ungenutze Funktionalitäten mit dieser Erweiterung ausblenden.
</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Wed, 04 Nov 2009 13:02:00 +0100</pubDate>
            <category>links</category>
            <category>web</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-11</guid>
            <title>Linktipps #11</title>
            <link>http://blackflash.nordic-dev.de/linktipps-11</link>
            <description><![CDATA[<ul>
<li><a target="_blank" href="http://adoseoflogic.blogspot.com/2009/07/cannibals-missionaries-and-state-monad_21.html">Cannibals, Missionaries and the State Monad pt. 2 </a>: Eine sehr empfehlenswerte Einführung in die State-Monade mit einigen hilfreichen Übungen - auch der <a target="_blank" href="http://adoseoflogic.blogspot.com/2009/07/cannibals-missionaries-and-state-monad.html">erste</a> und der <a target="_blank" href="http://adoseoflogic.blogspot.com/2009/08/cannibals-missionaries-and-state-monad.html">dritte Teil</a> sind lesenswert.</li><li><a target="_blank" href="http://netsuperbrain.com/blog/posts/applied-functional-programming-part-1/">Applied Functional Programming: Part 1</a>: Man kann funktionale Programmierung nicht nur benutzen, um funktionalen Code zu schreiben und zu verwenden, sondern auch um sinnvolle Semantiken in andere Sprachen zu übertragen, was an einem praxisorientierten Beispiel (OpenSSL) gezeigt wird.</li><li><a target="_new" href="http://kore-nordmann.de/blog/0093_svn_commit_hooks.html">SVN commit hooks</a>: Die Umsetzung einer Idee, die softwaretechnisch gesehen sehr interessant ist: Das Verhindern von Commits, die gegen bestimmte Regeln (Code-Guidelines, syntaktisch inkorrekter Code, ...) verstoßen.</li><li><a target="_new" href="http://chplib.wordpress.com/2009/09/18/the-sort-pump/">Concurrent Pearl: The Sort Pump</a>: Es wird ein paralleler Sortieralgorithmus, dessen Zeitkomplexität O(n) beträgt, entwickelt und erklärt. Nichtsdestotrotz bedeutet diese Komplexität nicht, dass der Algorithmus schneller als Quicksort läuft, da durch die Parallelisierung Kommunktionsüberhang zwischen den einzelnen Threads entsteht.</li><li><a target="_new" href="http://jacobian.org/writing/snakes-on-the-web/">Snakes on the Web</a>: Ein Python-Entwickler betrachtet die heutige Webentwicklung kritisch und liefert einige Vorschläge für die Zukunft.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 31 Oct 2009 18:30:00 +0100</pubDate>
            <category>algorithmen</category>
            <category>haskell</category>
            <category>links</category>
            <category>php</category>
            <category>softwaretechnik</category>
            <category>theorie</category>
            <category>web</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-10</guid>
            <title>Linktipps #10</title>
            <link>http://blackflash.nordic-dev.de/linktipps-10</link>
            <description><![CDATA[<ul>
<li><a href="http://www.oio.de/public/xml/rest-webservices.htm" target="_new">REST Web Services - Eine Einführung</a>: Die Einführung ist sehr ausführlich und enthält viele Beispiele und Grafiken, die einem guten Verständnis dienen. Insgesamt ist es eine sehr gute Aufarbeitung der Thematik.</li><li><a href="http://it-republik.de/jaxenter/artikel/REST---Der-bessere-Web-Service-2159.html" target="_new">REST - Der bessere Web Service?</a>: Eigentlich steht dieser Artikel stellvertretend für die gesamte Serie, in der er erschienen ist. Dennoch habe ich gerade diesen Artikel verlinkt, da er die wichtigsten Fakten und Meinungen zu dem Thema nennt.</li><li><a href="http://www.ibm.com/developerworks/java/library/wa-ajaxarch/index.html" target="_new">Ajax and REST</a>: Erklärt einige Ideen, <a href="http://blackflash.nordic-dev.de/architekturstil-ajax-und-rest" target="_new">über die ich bereits berichtet habe</a>, tiefgehend und stellt einige Implikationen dar.</li><li><a href="http://www.infoq.com/articles/designing-restful-http-apps-roth" target="_new">RESTful HTTP in practice</a>: Eine sehr praxisorientierte Einführung in RESTful Webservices, die kaum einen Wunsch offen lässt - was auch die Länge des Artikels erklärt.</li><li><a href="http://techportal.ibuildings.com/2009/09/07/graphs-in-the-database-sql-meets-social-networks/" target="_new">Graphs in the database: SQL meets social networks</a>: Dieser sehr ausführliche Artikel beschreibt, wie man Graphen und relationale Datenbanken miteinander verknüpfen kann.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 17 Oct 2009 09:47:00 +0200</pubDate>
            <category>datenbanken</category>
            <category>graphentheorie</category>
            <category>links</category>
            <category>softwaretechnik</category>
            <category>theorie</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-9</guid>
            <title>Linktipps #9</title>
            <link>http://blackflash.nordic-dev.de/linktipps-9</link>
            <description><![CDATA[<ul>
<li><a href="http://apfelmus.nfshost.com/fun-with-morse-code.html" target="_new">Fun with Morse Code</a>: Im Prinzip geht es zwar nur um das Kodieren und Dekodieren von Morse-Code, aber der Artikel ist sehr ausführlich und beschreibt neben verschiedenen Lösungswegen auch einige theoretische Aspekte wie Kategorientheorie oder GHC-Interna - sehr empfehlenswert.</li><li><a href="http://en.wikibooks.org/wiki/Haskell/Packaging">Haskell/Packaging</a>: Beschreibt Best Practices für Haskell-Projekte, u.a. <a href="http://darcs.net/" target="_new">darcs</a>, <a href="http://www.haskell.org/cabal/" target="_new">Cabal</a> und <a target="_new" href="http://en.wikipedia.org/wiki/QuickCheck">QuickCheck</a>.</li><li><a target="_new" href="http://www.haskell.org/haskellwiki/Debugging">Debugging in Haskell</a>: Eine kurze Einführung ins Haskell-Debugging mit einigen weiterführenden und lesenswerten Links.</li><li><a href="http://www.fatvat.co.uk/2009/09/exploring-haskells-list-functions.html">Exploring Haskell's List Functions</a>: Es wird ein Überblick über die wohl grundlegendste Datenstruktur in Haskell gegeben. Das interessanteste ist jedoch die weiterführende Literatur.</li><li><a href="http://www.ibm.com/developerworks/webservices/library/ws-restful/index.html" target="_new">RESTful Web services: The basics</a>: Eine schöne Einführung in RESTful Webservices.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 03 Oct 2009 09:58:00 +0200</pubDate>
            <category>haskell</category>
            <category>links</category>
            <category>softwaretechnik</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-8</guid>
            <title>Linktipps #8</title>
            <link>http://blackflash.nordic-dev.de/linktipps-8</link>
            <description><![CDATA[<ul>
<li><a href="http://blog.objectmentor.com/articles/2009/08/05/functional-refactoring-and-you-cant-get-there-from-here" target="_blank">Functional Refactoring and "You Can't Get There From Here"</a>: Eine interessante Beobachtung über das Refactoring in funktionalen Programmiersprachen.</li><li><a href="http://bjclark.me/2009/08/04/nosql-if-only-it-was-that-easy/" target="_blank">NoSQL: If Only It Was That Easy</a>: Sieben Datenbanksysteme werden auf Skalierbarkeit untersucht, um festzustellen, ob nicht-relationale Datenbanken wirklich besser skalieren als deren relationale Pendants. Leider wurde CouchDB in der Hinsicht nicht untersucht...</li><li><a target="_blank" href="http://blog.phpdeveloper.org/?p=169">Mom Always Said to Share</a>: In der Kindheit lernt man zu teilen und hier ist die Erklärung, wie bzw. weshalb man auch als Entwickler teilen kann bzw. sollte.</li><li><a target="_blank" href="http://therning.org/magnus/archives/735">Trying to work out iteratees</a>: Es wird ein Konzept, das in einem Kommentar als <em>standard stream fusion hylomorphism stuff with a left fold</em> beschrieben wurde, erläutert - wieder eine Herausforderung für mich.</li><li><a href="http://www.stubbles.org/archives/65-Extending-objects-with-new-methods-at-runtime.html" target="_new">Extending objects with new methods at runtime</a>: Wie der Titel bereits beschreibt, wird in diesem Artikel eine clevere Möglichkeit zum nachträglichen Hinzufügen von Methoden dargelegt.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 19 Sep 2009 08:17:00 +0200</pubDate>
            <category>datenbank</category>
            <category>haskell</category>
            <category>links</category>
            <category>php</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/hlint</guid>
            <title>HLint</title>
            <link>http://blackflash.nordic-dev.de/hlint</link>
            <description><![CDATA[<p>Aus der Beschreibung von <a target="_blank" href="http://hackage.haskell.org/package/hlint">HLint</a> geht hervor, dass es sich um ein Werkzeug handelt, das Hinweise für besseren Code gibt. Nachdem ich einen <a target="_blank" href="http://neilmitchell.blogspot.com/2009/09/how-i-use-hlint.html">Artikel über HLint</a> von <a target="_blank" href="http://neilmitchell.blogspot.com/">Neil Mitchell</a>, dem Autor von HLint, gelesen habe, installierte ich HLint sofort. Da die Installation per cabal aus unerfindlichen Gründen nicht funktioniert hat, habe ich es per <a target="_blank" href="http://wiki.archlinux.de/title/Yaourt">yaourt</a> installiert und über mein aktuelles Projekt laufen lassen. Nahezu augenblicklich hat mir HLint einige Hinweise gegeben, die ich verallgemeinert darstellen will:</p><ul><li><strong>Error: Use fromMaybe.</strong> Found <em>maybe x id</em>. Why not <em>fromMaybe x</em>?</li><li><strong>Error: Use isJust.</strong> Found <em>maybe False (const True)</em>. Why not <em>isJust</em>?</li><li><strong>Warning: Use liftM.</strong> Found <em>f x &gt;&gt;= return . g</em>. Why not <em>liftM g (f x)</em>?</li><li><strong>Warning: Eta reduce.</strong> Found <em>\x -&gt; liftM g (f x)</em>. Why not <em>liftM g . f</em>?</li></ul><p>Die letzte Meldung erschien übrigens nach Beheben der ersten drei Hinweise und abermaligem Ausführen von HLint. Dass solche Vereinfachungen, die in den Hinweisen angegeben werden, möglich sind, liegt vor allem daran, dass Haskell pur und statisch typisiert ist. Denn ohne Seiteneffekte lassen sich Haskell-Terme problemlos umformen - wie in der üblichen Arithmetik! Ich möchte das an den o.g. Beispielen illustrieren.</p>

<p>Zuerst beginnen wir mit den Definitionen der Funktionen <em>maybe</em>, <em>isJust</em> und <em>fromMaybe</em>, die in der Dokumentation zu <a target="_blank" href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Maybe.html">Data.Maybe</a> genannt werden.</p>
<ul>
<li><em>maybe</em>: The maybe function takes a default value, a function, and a Maybe value. If the Maybe value is Nothing, the function returns the default value. Otherwise, it applies the function to the value inside the Just and returns the result.</li><li><em>fromMaybe</em>: The fromMaybe function takes a default value and and Maybe value. If the Maybe is Nothing, it returns the default values; otherwise, it returns the value contained in the Maybe.</li><li><em>isJust</em>: The isJust function returns True iff its argument is of the form Just _.</li></ul><p>Daraus ergeben sich dann folgende Funktionsdefinitionen:</p>
<code name="code" class="haskell">maybe def f Nothing = def
maybe def f (Just x) = f x

fromMaybe def Nothing = def
fromMaybe def (Just x) = x

isJust (Just _) = True
isJust (Nothing) = False
</code>
<p>Für die nachfolgenden Umformungen sind auch die Funktionen <em>id</em>, die das Argument, was sie erhält, zurückliefert, und <em>const</em>, eine zweistellige Funktion, die das erste Argument zurückgibt und das zweite ignoriert, relevant. Es muss gezeigt werden, dass <em>maybe x id</em> und <em>fromMaybe x</em> zum gleichen Ergebnis kommen, d.h. <a target="_blank" href="http://de.wikipedia.org/wiki/Konfluenz_%28Informatik%29">konfluent</a> sind. Da es sich dabei um Funktionen handelt, müssen wir alle möglichen Werte <em>m</em> betrachten, die auf die Funktionen angewendet werden können. Hierfür müssen wir zwei Fälle betrachten: Entweder ist <em>m = Nothing</em> oder <em>m = Just y</em> für ein beliebiges <em>y</em>.</p>
<code>maybe x id m = fromMaybe x m
~&gt; { Einsetzen von m = Nothing }
maybe x id Nothing = fromMaybe x Nothing
~&gt; { Definition von maybe }
x = fromMaybe x Nothing
~&gt; { Definition von fromMaybe }
x = x

maybe x id m = fromMaybe x m
~&gt; { Einsetzen von m = Just y }
maybe x id (Just y) = fromMaybe x (Just y)
~&gt; { Definition von maybe }
id y = fromMaybe x (Just y)
~&gt; { Definition von id }
y = fromMaybe x (Just y)
~&gt; { Definition von fromMaybe }
y = y</code>
<p>Analog geht man im Fall vor, wenn man beweisen möchte, dass <em>maybe False (const True)</em> und <em>isJust</em> konfluent sind.</p>
<code>maybe False (const True) m = isJust m
~&gt; { Einsetzen von m = Nothing }
maybe False (const True) Nothing = isJust Nothing
~&gt; { Definition von maybe }
False = isJust Nothing
~&gt; { Definition von isJust }
False = False

maybe False (const True) m = isJust m
~&gt; { Einsetzen von m = Just y }
maybe False (const True) (Just y) = isJust (Just y)
~&gt; { Definition von maybe }
const True (Just y) = isJust (Just y)
~&gt; { Definition von const }
True = isJust (Just y)
~&gt; { Definition von isJust }
True = True</code>
<p>Auch monadische Terme sind leichter als gedacht. Ich habe dabei folgende Definition für liftM und die Funktionskomposition (.) gefunden:</p>
<code name="code" class="haskell">liftM f = \a -&gt; do { a' &lt;- a; return (f a') }
(.) f g = \a -&gt; f (g a)
</code>
<p>Da es sich im dritten Hinweis um eine nullstellige Funktion handelt, in der lediglich die ebenfalls nullstellige Funktion <em>x</em> frei ist - das ergibt sich aus der Logik der Funktion und nicht aus obigem Beispiel -, müssen wir die Konfluenz von <em>f x &gt;&gt;= return . g</em> und <em>liftM g (f x)</em> für alle <em>x</em> zeigen:</p>
<code>f x &gt;&gt;= return . g = liftM g (f x)
~&gt; { Definition von liftM }
f x &gt;&gt;= return . g = (\a -&gt; do { a' &lt;- a; return (g a') }) (f x)
~&gt; { Funktionsapplikation des Lambda-Ausdrucks mit (f x) }
f x &gt;&gt;= return . g = do { a' &lt;- (f x); return (g a') }
~&gt; { do-Notation }
f x &gt;&gt;= return . g = f x &gt;&gt;= \a' -&gt; return (g a')
~&gt; { Definition von (.) }
f x &gt;&gt;= \a -&gt; return (g a) = f x &gt;&gt;= \a' -&gt; return (g a')
~&gt; { a' in a umbenennen }
f x &gt;&gt;= \a -&gt; return (g a) = f x &gt;&gt;= \a -&gt; return (g a)
</code>
<p>Der Vollständigkeit halber folgt noch der triviale Beweis für die Konfluenz von <em>\x -&gt; liftM g (f x)</em> und <em>liftM g . f</em>.</p>
<code>\x -&gt; liftM g (f x) = liftM g . f
~&gt; { Definition von (.) }
\x -&gt; liftM g (f x) = \a -&gt; liftM g (f a)
~&gt; { a in x umbenennen }
\x -&gt; liftM g (f x) = \x -&gt; liftM g (f x)</code><p>Resümierend lässt sich sagen, dass funktionale Programmierspachen einen großen Vorteil bei der statischen Programmanalyse haben. Das trifft vor allem auf pure Sprachen wie Haskell zu. Vor allem lässt sich sehr leicht nachvollziehen, dass die vorgeschlagenen Änderungen nichts an der Semantik des Programms verändern - dem <a target="_blank" href="http://de.wikipedia.org/wiki/Lambda-Kalk%C3%BCl">Lambda-Kalkül</a> sei Dank.</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sun, 13 Sep 2009 09:26:00 +0200</pubDate>
            <category>haskell</category>
            <category>theorie</category>
            <category>verifikation</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/php-magazin-6-09</guid>
            <title>PHP-Magazin 6.09</title>
            <link>http://blackflash.nordic-dev.de/php-magazin-6-09</link>
            <description><![CDATA[<p>Heute ist das <a href="http://it-republik.de/php/" target="_new">PHP-Magazin</a> der Ausgabe 6.09 in meinem Briefkasten gelandet, weshalb ich über jeden Artikel einige Worte verlieren möchte.</p>

<ul>
<li><strong>News</strong>: Hier entscheidet die eigene Interessenslage, ob man diese Neuigkeiten als relevant empfindet - auffallend war jedoch, dass in drei der fünf Neuigkeiten ein Preis von 1595 Euro bis 8.900 US-Dollar genannt wurde.</li><li><strong>PEAR-News</strong>: Ein sehr kurzer Überblick, da der Seitenkopf und die Werbung ca. 50% der Seite einnehmen, über die wahrscheinlich wichtigsten und interessantesten PEAR-Komponenten.</li><li><strong>Let's talk about ez Components</strong>: Man kann geteilter Meinung über die Relevanz dieses Artikels sein, auch wenn der Inhalt gut erklärt ist.</li><li><strong>Nils Langner im Gespräch mit Johannes Schlüter</strong>: Das Interview mit dem Release-Manager von PHP 5.3 ist sehr interessant, da es viele Informationen zur PHP-Community und dem PHP-Projekt enthält, die interessant, wichtig oder beides sind. Man sollte dabei einige genannte Fakten im Hinterkopf behalten, wenn man das nächste Mal einen unvollständigen Bug-Report einsenden möchte. Eine unwichtige Frage stellt sich mir dabei jedoch: Wieso gibt es kein Porträt von Herrn Schlüter?</li><li><strong>Ein Neuer ist in der Stadt</strong>: Eine gelungene Übersicht über die Funktionalitäten des Zend Servers, der in der Community Edition auch kostenfrei zur Verfügung steht. Könnte für den ein oder anderen Entwickler durchaus interessant sein.</li><li><strong>.NET calling PHP</strong>: Der Beginn des Artikels wartet mit einer kurzen Einführung in SOAP-Webservices auf. Anschließend geht es um die Implementierung eines PHP-basierten Webservices, der kompatibel zu .NET-Clients ist, worauf auch der Fokus dieses Artikels liegt. Insgesamt ist der Artikel lesenswert, da die meisten Informationen in ggf. abgewandelter Form auch für andere Clients gilt.</li><li><strong>Wenn der Server dreimal klingelt</strong>: "Ein Blick über den Tellerrand" ist eine sehr passende Bezeichnung für diesen Artikel, da er ein Thema behandelt, mit dem die wenigsten PHP-Entwickler zu tun haben werden: Das Ansteuern der Telefonanlage Asterisk mittels PHP. Dennoch finde ich den Artikel recht interessant.</li><li><strong>Subclipse und ihre Schwestern</strong>: Leider ist der Artikel sehr kurz geraten, weshalb nur eine begrenzte Anzahl an Konfigurationsmöglichkeiten beschrieben werden. Dennoch hat der Artikel mich dazu bewegt, Subversive, eine Alternative zu Subclipse, auszuprobieren. Außerdem wurden beiläufig einige mir noch unbekannte Fakten erwähnt, die für den Subversion-Kenner wahrscheinlich alte Hüte darstellen.</li><li><strong>Ready for Enterprise</strong>: Hinter dem nichtssagenden Titel verbirgt sich ein Artikel über das Puppet-Framework mit dessen Hilfe sich der Aufwand für Systemadministratoren drastisch reduzieren lässt, da man quasi ein Rezept angibt, wie das System am Ende aussehen soll, das Puppet dann abarbeitet. Diesen Artikel kann ich jedem uneingeschränkt empfehlen.</li><li><strong>Up to date</strong>: Übliche Fallstricke und Strategien bei der Migration von PHP-Versionen im Allgemeinen und auf PHP 5.3 im Speziellen werden durch diesen Artikel abgedeckt. Man merkt dem Artikel an, dass der Autor bereits ein Buch über dieses Thema geschrieben hat - sehr empfehlenswert für diejenigen, die mit der Problematik der Migration konfrontiert sind.</li><li><strong>Reporting mit BIRT</strong>: Wahrscheinlich ist die Anleitung nur für Personen interessant, denen es nützt, eine solche Software zu verwenden. Ich persönlich konnte hingegen so gut wie nichts aus dem Artikel mitnehmen.</li> 
<li><strong>Alles machbar</strong>: Auch wenn der Artikel einen sehr guten Überblick über die Entwicklung mit Oracle mittels PHP bietet, macht er keine Lust auf ein tieferes Eintauchen in die Oracle-Welt, was vor allem einigen antipathischen Kommentaren des Autors geschuldet ist.</li><li><strong>Out now! PostgreSQL 8.4</strong>: Der Artikel an sich ist sehr gelungen und macht Lust auf mehr PostgreSQL.</li><li><strong>Verteilte Herrschaft</strong>: Es wird ein kurzer Überblick über gängige Strategien gegeben, wenn ein einzelner MySQL-Server nicht mehr ausreicht. Dabei handelt es sich vor allem um Grundlagen, die man im Kopf behalten sollte.</li><li><strong>Benimm dich!</strong>: Der einzige Artikel, der mich in keiner Weise dazu animiert hat, ihn zu lesen.</li><li><strong>Vernetzt</strong>: Ein sehr gut ausgearbeiteter Artikel über das semantische Web. Es werden viele Ideen und Formate, aber auch einige geschichtliche Hintergründe geliefert. Wieder ein sehr lesenswerter Artikel, da er sich mit dem beschäftigt, was man als Nachfolger vom Web 2.0 handelt.</li></ul><p>Insgesamt war diese Ausgabe ziemlich gut, auch wenn man merkt, dass einige der Autoren Laien auf dem Gebiet des Schreibens sind, wie z.B. "Auch das CLI des PostgreSQL hat sein Fett wegbekommen.", "angucker" oder "Richtig durchgeknallt wird es, [...]". Dem Inhalt hat dies zumeist keinen Abbruch getan. Übrigens liegt dem Magazin - zumindest im Abonnement - ein Poster über PHP-Web-Security im DIN-A0-Format bei.</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 12 Sep 2009 17:18:00 +0200</pubDate>
            <category>php</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-7</guid>
            <title>Linktipps #7</title>
            <link>http://blackflash.nordic-dev.de/linktipps-7</link>
            <description><![CDATA[<ul>
<li><a target="_blank" href="http://bergie.iki.fi/blog/will_content_repositories_kill_the_file/">Will content repositories kill the file?</a>: Zwar ein sehr kurzer Artikel, dafür regte er mich jedoch zum Denken an.</li><li><a target="_blank" href="http://kore-nordmann.de/blog/do_NOT_parse_using_regexp.html">Do NOT try parsing with regular expressions</a>: Kore beschreibt mithilfe des Pumping-Lemmas (für reguläre Sprachen), dass rekursive Strukturen nicht durch reguläre Sprachen erzeugt werden können und dass <a target="_blank" href="http://www.pcre.org/">PCRE</a> deshalb nicht zum Parsen dieser Strukturen verwendet werden sollten, was er im <a target="_blank" href="http://kore-nordmann.de/blog/parse_with_regexp.html">weiterführenden Artikel</a> auch kurz erläutert.</li><li><a target="_blank" href="http://koweycode.blogspot.com/2009/07/some-ideas-for-practical-quickcheck.html">some ideas for practical QuickCheck</a>: Die Antworten auf einige Fragen zum <a target="_blank" href="http://koweycode.blogspot.com/2009/02/practical-quickcheck-wanted.html">praktischen Einsatz von Quickcheck</a>.</li><li><a target="_blank" href="http://www.dumblittleman.com/2009/07/eight-reasons-to-read-fiction.html">Eight Reasons to Read Fiction</a>: Acht gute Gründe, weshalb man neben Fachliteratur auch Belletristik lesen sollte.</li><li><a target="_blank" href="http://www.survivethedeepend.com/">Survive the Deep End</a>: Ein freies Buch über das Zend Framework im HTML-Format.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sun, 06 Sep 2009 08:27:00 +0200</pubDate>
            <category>couchdb</category>
            <category>links</category>
            <category>php</category>
            <category>theorie</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/data-default</guid>
            <title>Data.Default</title>
            <link>http://blackflash.nordic-dev.de/data-default</link>
            <description><![CDATA[<p>Gestern bin ich auf ein Modul namens <a target="_blank" href="http://hackage.haskell.org/package/data-default">Data.Default</a> gestoßen, das eine smarte Möglichkeit zum Definieren von Standardwerten bietet. Zwar mag diese Eigenschaft recht unspektakulär wirken, aber in Verbindung mit <a target="_blank" href="http://en.wikipedia.org/wiki/Type_inference">Typinferenz</a> sehr interessant ist. Auch die Definition der Typklasse ist sehr unspektakulär:</p>
<code name="code" class="haskell">class Default a where
	def :: a
</code>
<p>Für Instanzen dieser Typklasse muss also nur die Funktion <em>def</em> definiert werden, die lediglich den Standardwert des jeweiligen Typs darstellt. Einige Typinstanzen, die im o.g. Modul definiert wurden, sehen folgendermaßen aus:</p>
<code name="code" class="haskell">instance Default Int where def = 0
instance Default [a] where def = []
instance Default (Maybe a) where def = Nothing
</code><p>Nun ist man in der Lage <em>def</em> innerhalb des Codes zu verwenden. Das Elegante an dieser Typklasse ist, dass def durch den gerade benötigten Wert ersetzt wird und man somit nicht mehr explizit darauf achten muss, dass ein gültiger Standardwert gewählt wird, denn das übernimmt der Compiler. Hierzu ein weiteres Beispiel (aus <a target="_blank" href="http://github.com/nfjinjing/hack/blob/00ac959e448ac8a92e6d39a2f019f2b1d921a845/src/Hack.hs">Hack.hs</a>):</p>
<code name="code" class="haskell">data Response = Response
 { status :: Int
 , headers :: [(String, String)]
 , body :: L.ByteString
 }
 deriving (Show)

instance Default Response where
 def = Response def def L.empty
</code><p>Bei der Instanzierung der <em>Default</em>-Typklasse von <em>Response</em> lässt sich erahnen, dass diese Verwendung sinnvoll ist. Zum einen wird der Code klarer, aber zum anderen braucht man sich bei einem Refactoring, z.B. wenn der Typ geändert wird, nicht darum kümmern, dass der richtige Standardwert gesetzt wird, denn der wird automatisch vom Compiler ausgewählt - man muss natürlich sicherstellen, dass ein Standardwert existiert. Derzeit ist das Feld <em>status</em> vom Typ <em>Int</em>, aber da es sich um HTTP-Codes handelt, könnte man einen weiteren Typ einführen, der nur gültige HTTP-Codes annehmen kann. Würde man diesen neuen Typ in der <em>Default</em>-Typklasse instanzieren, bräuchte man beim Setzen von Standardwerten keine Zeile zu verändern.</p><p>Zwar ist diese Idee nicht revolutionär, aber für mich zeigt sie sehr schön die Vorzüge von Typinferenz und statisch-typisierten Programmiersprachen im Allgemeinen und Haskell im Speziellen.</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Fri, 04 Sep 2009 15:22:00 +0200</pubDate>
            <category>haskell</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/haskell-hack-und-fastcgi</guid>
            <title>Haskell, Hack und FastCGI</title>
            <link>http://blackflash.nordic-dev.de/haskell-hack-und-fastcgi</link>
            <description><![CDATA[<p>Bereits vor einiger Zeit bin ich auf ein interessantes Projekt namens <a target="_blank" href="http://blog.snoyman.com/2009/06/28/hack-introduction/">Hack</a> (von Jinjing Wang) gestoßen, das eine Schnittstelle für Webapplikation jeglicher Art darstellen soll, was über Handler realisiert wird. So sind bereits Handler für <a target="_blank" href="http://happstack.com/">Happstack</a>, <a target="_blank" href="http://hackage.haskell.org/package/kibro">Kibro</a>, CGI, <a target="_blank" href="http://hackage.haskell.org/package/hack-handler-fastcgi">FastCGI</a> und einigen weiteren entstanden. Da ich <a target="_blank" href="http://www.lighttpd.net/">Lighttpd</a> als Webserver verwende und die Konfiguration mittels FastCGI mit Lighttpd sehr leicht zu machen ist, habe ich mich kurzerhand entschlossen, Hack eine Chance zu geben.</p>
<p>Der erste Schritt war das Installieren der benötigten <a target="_blank" href="http://hackage.haskell.org/packages/hackage.html">Hackage-Pakete</a>. Da ArchLinux bisher verhältnismäßig viele Hackage-Pakete angeboten hat, habe ich das benötigte <em>haskell-hack-handler-fastcgi</em> mitsamt der Abhängigkeiten installiert per <a target="_blank" href="http://wiki.archlinux.de/title/Yaourt">yaourt</a>. Die Verwendung von <em>cabal</em> würde jedoch genauso gut funktionieren. Da Lighttpd bereits installiert war, war nur die Konfiguration desselben notwendig. Hierfür habe ich einen virtuellen Host (taskell), der auf 127.0.0.1 zeigt, angelegt:</p>
<code>$HTTP["host"] == "taskell" {
 server.name = "taskell"
 server.document-root = "/home/blackflash/workspace/Taskell/src"
 fastcgi.server = (
 "/" =&gt; (
 "taskell" =&gt; (
 "socket" =&gt; "/tmp/taskell.socket",
 "check-local" =&gt; "disable",
 "bin-path" =&gt; "/home/blackflash/workspace/Taskell/src/Main",
 "min-procs" =&gt; 1,
 "max-procs" =&gt; 30,
 "idle-timeout" =&gt; 30
 )
 )
 )
}</code>
<p>Natürlich ist das nur eine rudimentäre Konfiguration zum Überprüfen, ob es überhaupt funktioniert, denn man sollte niemals direkt in den Workspace verlinken. Die Datei Main entspricht übrigens der kompilierten Main.hs, dessen Inhalt folgendermaßen aussieht:</p>
<code class="haskell" name="code">module Main where

import Hack
import Hack.Handler.FastCGI
import Data.ByteString.Lazy.Char8 (pack)

main :: IO ()
main = runFastCGI app

app :: Application
app = return . Response 200 [ ("Content-Type", "text/plain") ] . (pack . show)</code>
<p>In der main-Funktion wird die Anbindung der Applikation app an FastCGI realisiert. Derzeit besteht sie nur aus dem Zusammenstellen einer HTTP-Antwort (200 OK) mit der Umgebung als Antwort. Eine Anfrage an den Webserver sieht dann folgendermaßen aus:</p>
<code># curl http://taskell/
Env {requestMethod = GET, scriptName = "/", pathInfo = "", queryString = "", serverName = "taskell", serverPort = 80,
http = [("FCGI_ROLE","RESPONDER"),("SERVER_SOFTWARE","lighttpd/1.4.23"),
("SERVER_NAME","taskell"),("GATEWAY_INTERFACE","CGI/1.1"), ("SERVER_PORT","80"),
("SERVER_ADDR","127.0.0.1"),("REMOTE_PORT","56072"),("REMOTE_ADDR","127.0.0.1"),
("SCRIPT_NAME","/"),("PATH_INFO",""),("SCRIPT_FILENAME","/home/blackflash/workspace/Taskell/src/"),
("DOCUMENT_ROOT","/home/blackflash/workspace/Taskell/src"),("REQUEST_URI","/"),
("QUERY_STRING",""),("REQUEST_METHOD","GET"),("REDIRECT_STATUS","200"),
("SERVER_PROTOCOL","HTTP/1.1"),
("User-Agent","curl/7.19.6 (i686-pc-linux-gnu) libcurl/7.19.6 OpenSSL/0.9.8k zlib/1.2.3.3"),
("Host","taskell")("Accept","*/*")], hackVersion = [2009,7,15], hackUrlScheme = HTTP,
hackInput = Empty, hackErrors = Error Stream, hackHeaders = [], hackCache = []}</code>
<p>Insgesamt war das Aufsetzen einer solchen "Hallo Welt"-Applikation sehr einfach. Man benötigt dazu lediglich eine Informationsquellen (neben dem Quellcode), die ich hier der Vollständigkeit halber noch erwähnen möchte:</p><ul><li><a target="_blank" href="http://github.com/nfjinjing/hack/blob/00ac959e448ac8a92e6d39a2f019f2b1d921a845/src/Hack.hs">Hack.hs</a>: Das Hack-Modul, das die Umgebung beschreibt.</li><li><a target="_blank" href="http://github.com/nfjinjing/hack/blob/00ac959e448ac8a92e6d39a2f019f2b1d921a845/readme.md">readme.md</a>: Eine Art Kurztutorial, das vom Hack-Autor geschrieben wurde.</li><li><a target="_blank" href="http://blog.snoyman.com/2009/06/28/hack-introduction/">Hack Introduction</a>: Eine konzeptionelle Einführung in Hack, die für das Verständnis sehr hilfreich ist.</li></ul><p>Es sei noch angemerkt, dass ich einige Punkte wie das Kompilieren der <em>Main.hs</em> sowie das Neustarten des Webservers und das Eintragen des Hosts <em>taskell</em> nicht erläutert habe, was daran liegt, dass dieser Artikel kein Tutorial darstellt, sondern lediglich einen Überblick über FastCGI-Entwicklung mit Hack und Haskell bietet.</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Fri, 28 Aug 2009 16:05:00 +0200</pubDate>
            <category>haskell</category>
            <category>links</category>
            <category>web</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/architekturstil-ajax-und-rest</guid>
            <title>Architekturstil: Ajax und REST</title>
            <link>http://blackflash.nordic-dev.de/architekturstil-ajax-und-rest</link>
            <description><![CDATA[<p>Der Trend geht derzeit zu <a target="_blank" href="http://de.wikipedia.org/wiki/Rich_Internet_Application">Rich Internet Application</a>s (RIA), weshalb ich mir Gedanken über dieses Thema gemacht habe. Für mich als Informatiker stellte sich vordergründig die Frage, wie sich solche Applikationen technisch elegant realisieren ließen. Dabei ging es mir konkret um einen <a target="_blank" href="http://de.wikipedia.org/wiki/Architekturmuster">Architekturstil</a> für solche Anwendungen.</p><p>Zuerst ist es jedoch wichtig zu wissen, wie konventionelle Webapplikationen entwickelt werden und welche Architektur sie nutzen, damit man die Limitationen derselben erkennt und sie derart modifizieren kann, dass sie sich gut für RIAs eignen. Der synchrone Mechanismus hat sich seit der Einführung des <a target="_blank" href="http://de.wikipedia.org/wiki/HTTP">HTTP</a> nicht geändert:</p><ol><li>Der Benutzer stellt eine Anfrage an den Webserver.</li><li>Der Webserver empfängt die Anfrage und generiert eine HTML-Webseite.</li><li>Der Webserver sendet die Antwort zum Benutzer.</li></ol></li><p>Auch bei dynamischen Webseiten wird dieser Mechanismus nur mit kleinen Änderungen verwendet. Was vor allem bemerkenswert ist, dass i.d.R. die komplette Webseite (in Form von HTML) zurückgesendet wird, was meist viele redundante Daten einschließt. Im Zuge des Web 2.0 gab es eine Entwicklung zu asynchronen Anfragen, bei der nur Teile einer Webseite neugeladen werden. Als Format der Wahl bei diesen asynchronen Anfragen wird kein HTML verwendet, sondern auf XML oder neuerdings auch <a target="_blank" href="http://de.wikipedia.org/wiki/JSON">JSON</a> gesetzt. Ermöglicht wird dieser asynchrone Nachrichtenaustausch durch <a target="_blank" href="http://de.wikipedia.org/wiki/JavaScript">JavaScript</a>, woraus sich letztendlich das Akronym <a target="_blank" href="http://de.wikipedia.org/wiki/Ajax_%28Programmierung%29">Ajax</a> ergibt. Führt man dieses Konzept konsequent weiter, gelangt man zu einem Architekturstil, der auf synchronen Nachrichtenaustausch soweit wie möglich verzichtet.</p><p>Wie lässt sich ein solcher Architekturstil jedoch umsetzen? Da die Applikationslogik aus offensichtlichen Gründen nicht beim Benutzer ausgeführt werden kann, benötigt man eine Komponente, die diesen Part übernimmt: Ein <a target="_blank" href="http://de.wikipedia.org/wiki/Webservice">Webservice</a>. Konkret bietet sich hierfür eine leichtgewichtige Art von Webservice an, die auf Ideen des HTTP aufbaut: <a target="_blank" href="http://de.wikipedia.org/wiki/Representational_State_Transfer">Representational State Transfer</a> (REST). Es wird also ein sog. RESTful Webservice benötigt. Im Gegensatz zu konventionellen Webapplikationen würde ein solcher Webservice weitaus mehr Anfragen erhalten, die allerdings weitaus kürzer ausfallen - statt einer gesamten HTML-Webseite werden dem Client lediglich die benötigten Daten zur Darstellung gesendet. Betrachtet man dieses Konzept aus Sicht des <a target="_blank" href="http://de.wikipedia.org/wiki/MVC">MVC</a>-Architekturmusters, so stellen sich die Zuständigkeiten folgendermaßen dar:</p><ul><li>Modell: Der Webservice enthält die Geschäftslogik.</li><li>View: Der Webserver enthält die Rohfassung des Views und der Client weiß, wie er den View mit Daten aus dem Modell füllen kann.</li><li>Controller: Auf dem Client werden die Benutzerinteraktionen abgehandelt.</li></ul><p>Man erkennt eine klare Trennung zwischen Modell und View/Controller bzw. Webservice und Client. Durch diese konsequente Trennung wird man zu einer präzisen Beschreibung des Webservices gezwungen, was der Qualität des Softwareprodukts zugute kommen sollte. Ein weiterer Nebeneffekt ist, dass die Last zum Teil vom Server auf die Clients verteilt wird, was bei den Clients kaum ins Gewicht fällt, aber für den Server spürbare Auswirkungen hat.</p><p>Ich für meinen Teil finde diesen Architekturstil sehr interessant, weshalb ich ihn ein wenig erkunden möchte. Welche Komponenten benötigt man also dafür? Zum einen braucht man eine gute Ajax-Bibliothek (z.B. <a target="_blank" href="http://www.dojotoolkit.org/">Dojo</a>, <a target="_blank" href="http://www.prototypejs.org/">prototype.js</a>) und zum anderen neben einem Webserver natürlich ein Framework mit dessen Hilfe man RESTful Webservices. Da Frontend-Entwicklung nicht zu meinen Interessen gehört und die Anforderungen an den Webservice sehr hoch sind, werde ich mich in naher Zukunft mit diesem Thema beschäftigen, wobei es derzeit nach einer <a target="_blank" href="http://www.haskell.org/">Haskell</a>-Lösung mittels <a target="_blank" href="http://de.wikipedia.org/wiki/FastCGI">FastCGI</a> aussieht, was der <a target="_blank" href="http://shootout.alioth.debian.org/u32q/benchmark.php?test=all&lang=ghc&lang2=php&box=1">Geschwindigkeit</a> von Haskell und meinem Interesse an <a target="_blank" href="http://de.wikipedia.org/wiki/Funktionale_Programmierung">funktionalen Programmiersprachen</a> geschuldet ist. Zu diesem Thema werde ich euch natürlich auf dem Laufenden halten.</p><p>Insgesamt scheint die Idee älter zu sein, als ich angenommen habe, da bereits 2006 ein Artikel über <a target="_blank" href="http://www.ibm.com/developerworks/java/library/wa-ajaxarch/index.html">Ajax und REST</a>
erschienen ist - weshalb hat sie sich bisher nicht durchgesetzt? Oder
wird sie bereits exzessiv eingesetzt und es ist mir nur noch nicht
aufgefallen? Solltet ihr mehr zu diesem Thema wissen oder eine Meinung zu diesem Thema haben, würde ich mich natürlich freuen, wenn ihr mich darüber unterrichtet.</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Tue, 25 Aug 2009 10:08:00 +0200</pubDate>
            <category>softwaretechnik</category>
            <category>web</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-6</guid>
            <title>Linktipps #6</title>
            <link>http://blackflash.nordic-dev.de/linktipps-6</link>
            <description><![CDATA[<ul>
<li><a target="_blank" href="http://www.sitepoint.com/blogs/2009/07/13/php-53-namespaces-basics/">How to Use PHP Namespaces, Part 1: The Basics</a>: Der Einstieg erklärt die Grundlagen zu Namespaces und deren Sinn.</li><li><a target="_blank" href="http://www.sitepoint.com/blogs/2009/07/14/php-namespaces-import-alias-resolution/">How to Use PHP Namespaces, Part 2: Importing, Aliases, and Name Resolution</a>: Im zweiten Teil der Trilogie werden Begriffe und die Funktionsweise geklärt und Hinweise zur Nutzung gegeben.</li><li><a target="_blank" href="http://www.sitepoint.com/blogs/2009/07/15/how-to-use-php-namespaces-part-3-keywords-and-autoloading/">How to Use PHP Namespaces, Part 3: Keywords and Autoloading</a>: Der finale Teil zeigt nützliche Methoden und Konstanten auf, die für Fortgeschrittene sicherlich von großem Wert sein dürften.</li><li><a target="_blank" href="http://www.heise.de/newsticker/Tom-deMarco-sieht-Ende-des-Software-Engineering--/meldung/142540">Tom deMarco sieht Ende des Software-Engineering</a>: Sowohl der Heise- als auch der verlinkte Artikel von Tom deMarco ist sehr lesenswert. Es geht um seine Ansicht zur Situation des Software-Engineerings. Auch wenn man nicht seiner Meinung sein muss, gibt er einige interessante Denkanstöße.</li><li><a target="_blank" href="http://www.sdtimes.com/blog/post/2009/07/27/Everyonee28099s-talking-about-Haskell.aspx">Everyone's talking about Haskell</a>: Ein Art von Interview, das über Haskell geführt wurde. Es geht vor allem um einen Überblick, wo Haskell industriell eingesetzt wird bzw. eingesetzt werden kann.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 22 Aug 2009 09:07:00 +0200</pubDate>
            <category>haskell</category>
            <category>links</category>
            <category>php</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/uncle-bobs-bowling-game-kata</guid>
            <title>Uncle Bob’s Bowling Game Kata</title>
            <link>http://blackflash.nordic-dev.de/uncle-bobs-bowling-game-kata</link>
            <description><![CDATA[<p>Vor zwei Tagen gab es auf <a target="_blank" href="http://programmingpraxis.com/">ProgrammingPraxis.com</a> die Aufgabe <a target="_blank" href="http://programmingpraxis.com/2009/08/11/uncle-bobs-bowling-game-kata/">Uncle Bob’s Bowling Game Kata</a> durchzuführen. Bei dieser Kata geht es darum, anhand von der umgefallenen Pins die Gesamtpunktzahl einer Bowling-Runde zu ermitteln. Die in Haskell angefertigte Lösung ist sehr elegant, weshalb ich sie hier präsentieren und verifizieren will. Aber davor müssen noch einige wichtige Begriffe und natürlich die Regeln erklärt werden (vgl. <a target="_blank" href="http://de.wikipedia.org/wiki/Bowlingregeln">Bowlingregeln</a>).</p><ul><li>Bowling-Runde: Die Bowling-Runde besteht aus 10 Frames.</li><li>Frame: Ein Frame endet entweder nach zwei Würfen oder nach einem Strike.</li><li>Strike: Alle 10 Pins wurden nach dem ersten Wurf getroffen. Zusätzlich zu den 10 Punkten werden die nächsten beiden Würfe addiert.</li><li>Spare: Alle 10 Pins wurden nach dem zweiten Wurf getroffen. Zusätzlich zu den 10 Punkten wird der nächste Wurf addiert.</li><li>Offener Frame: Es wurden mit den beiden Würfen weniger als 10 Pins getroffen.</li><li>Miss: Es wurde kein Pin getroffen.</li><li>Letzter Frame: Die Runde hat mindestens zwei und maximal drei Würfe deren Summe zum Ergebnis addiert wird. Der dritte Wurf wird genau dann gewährt, wenn ein Strike oder Spare geworfen wurde.</li><li>Punktzahl: Die Anzahl der getroffenen Pins bei einem Wurf.</li></ul><p>Die folgende Grafik zeigt einen beispielhaften Verlauf (entnommen von ProgrammingPraxis.com):</p>
<img  src="http://programmingpraxis.files.wordpress.com/2009/08/tenpins.jpg"><p>Ist ein Kästchen zur Hälfe ausgefüllt, so wurde ein Spare geworfen, d.h. es wurden 10 Punkte in dem Frame geworfen. Bei einem vollständig ausgefülltem Kästchen wurde ein Strike geworfen, d.h. mit einem Wurf wurden 10 Pins getroffen. In der obigen Darstellung steht in der unteren Zeile die Gesamtpunktzahl nach dem jeweiligen Frame, wobei die speziellen Regeln für Strikes, Spares und den letzten Frame bereits berücksichtigt wurden.</p><p>Meine Implementierung macht sich diese Regelunterscheidungen zunutze:</p>
<code class="haskell" name="code">
pins [x,y] = x+y  -- last frame
pins [x,y,z] = x+y+z  -- last frame
pins (x:y:z:xs)
 | x == 10 = 10+y+z + pins (y:z:xs) -- Strike
 | x+y == 10 = 10+z + pins (z:xs) -- Spare
 | otherwise = x+y + pins (z:xs) -- open frame
</code>
<p>Die Erklärung des Codes erfolgt dabei direkt anhand der Verifikation der Korrektheit. Es wird der Einfachheit halber angenommen, dass die Würfe als Liste von Punktzahlen übergeben wird, d.h. Strikes, Spares oder Misses werden anhand der Punktzahlen ermittelt. Außerdem kann vorausgesetzt werden, dass die Eingabe korrekt ist. Eine wesentliche Eigenschaft zur Verifikation ist die Invariante, die besagt, dass bei einem Aufruf der Funktion <em>pins</em> genau ein Frame abgearbeitet wird.</p><p>Beginnen wir bei der Berechnung des letzten Frames: Der letzte Frame enthält entweder drei oder zwei Würfe. Hier wird lediglich die Gesamtpunktzahl des Frames ermittelt. Durch das Pattern-Matching werden nur die Fälle abgearbeitet, in denen die Liste zwei oder drei Punktzahlen, sodass die Regeln, wie definiert, nur im letzten Frame gilt. Die Regeln entsprechen offensichtlich dem, was in der Definition des letzten Frames angegeben wurde. Außerdem gilt die Invariante, da der letzte Frame in Gänze abgearbeitet wird.</p><p>Der andere Fall wird genau dann aufgerufen, wenn der letzte Frame noch nicht erreicht ist. Zuerst wird die Invariante gezeigt: Wurde ein Strike geworfen, hat der Frame nur einen Wurf, d.h. nur der Kopf der Liste (d.h. <em>x</em>) wird verarbeitet. In den restlichen Fällen werden die ersten beiden Elemente verarbeitet (d.h. <em>x</em> und <em>y</em>). Dies ist offensichtlich der Fall, da die jeweiligen Elemente in den nachfolgenden Aufrufen nicht mehr verarbeitet werden. Die Regeln werden regelkonform übernommen: Bei einem Strike werden die nächsten beiden (d.h. <em>y</em> und <em>z</em>), bei einem Spare nur die nächste (d.h. <em>z</em>) sowie bei einem offenen Frame keine weiteren Punktzahlen zur Gesamtpunktzahl des jeweiligen Frames addiert.</p><p>Da die Regeln jeweils korrekt übertragen wurden, wird die Gesamtpunktzahl jedes Frames korrekt berechnet. Es kann als bekannt vorausgesetzt werden, dass sich die Gesamtpunktzahl einer Bowling-Runde aus der Gesamtpunktzahl jedes einzelnen Frames ergibt. Da <em>pins</em> lt. Invariante jeweils einen Frame korrekt berechnet und diese Punktzahl anschließend auf Gesamtpunktzahl der restlichen Frames addiert wird, ist auch die Summe korrekt. Für das Verständnis exerziere ich die Funktionsweise am Beispiel der obigen Grafik durch:</p>
<code>pins [1,4,4,5,6,4,5,5,10,0,1,7,3,6,4,10,2,8,6]
= {open frame}
(1+4) + (pins [4,5,6,4,5,5,10,0,1,7,3,6,4,10,2,8,6])
= {open frame}
5 + (4+5) + (pins [6,4,5,5,10,0,1,7,3,6,4,10,2,8,6])
= {spare}
5 + 9 + (10+5) + (pins [5,5,10,0,1,7,3,6,4,10,2,8,6])
= {spare}
5 + 9 + 15 + (10+10) + (pins [10,0,1,7,3,6,4,10,2,8,6])
= {strike}
5 + 9 + 15 + 20 + (10+0+1) + (pins [0,1,7,3,6,4,10,2,8,6])
= {open frame}
5 + 9 + 15 + 20 + 11 + (0+1) + (pins [7,3,6,4,10,2,8,6])
= {spare}
5 + 9 + 15 + 20 + 11 + 1 + (10+6) + (pins [6,4,10,2,8,6])
= {spare}
5 + 9 + 15 + 20 + 11 + 1 + 16 + (10+10) + (pins [10,2,8,6])
= {strike}
5 + 9 + 15 + 20 + 11 + 1 + 16 + 20 + (10+2+8) + (pins [2,8,6])
= {last frame}
5 + 9 + 15 + 20 + 11 + 1 + 16 + 20 + 20 + 16
= {+}
14 + 15 + 20 + 11 + 1 + 16 + 20 + 20 + 16
= {+}
29 + 20 + 11 + 1 + 16 + 20 + 20 + 16
= {+}
49 + 11 + 1 + 16 + 20 + 20 + 16
= {+}
60 + 1 + 16 + 20 + 20 + 16
= {+}
61 + 16 + 20 + 20 + 16
= {+}
77 + 20 + 20 + 16
= {+}
97 + 20 + 16
= {+}
117 + 16
= {+}
133</code>
<p>Anhand dieses Beispiels kann man sehr gut erkennen, wie der Algorithmus arbeitet. Zuerst wird jeder einzelne Frame berechnet und anschließend dessen Summe gebildet. Zwar hat die Auswertungsreihenfolge lt. <a target="_blank" href="http://de.wikipedia.org/wiki/Church-Rosser-Theorem">Church-Rosser-Theorem</a> keinen Einfluss auf das Ergebnis, aber die obige Reihenfolge ist für das Verständnis sehr gut geeignet. Ein Vergleich mit den <a target="_blank" href="http://blog.moertel.com/articles/2006/04/05/the-bowling-game-kata-in-haskell">korrigierten Testfällen</a> auf <a target="_blank" href="http://blog.moertel.com/">Tom Moertels Blog</a> bekräftigt dieses Ergebnis.</p><p>Insgesamt bin ich sehr zufrieden mit meiner Lösung, da sie sehr kurz aber auch sehr präzise ist. Soweit ich weiß, sollten solche Code-Katas testgetrieben entwickelt werden, was in diesem Fall allerdings sehr wenig Sinn hat, denn sechs Zeilen Code sind schneller geschrieben als die Unit-Tests und man kann sich sehr leicht von der Korrektheit überzeugen. Wenn man beim Schreiben des Codes bereits plant, den Code zu verifzieren, macht man sich automatisch Gedanken darüber, wie man das Problem dekomponieren und die Teillösungen komponieren kann. In meinem Fall wurde die Gesamtpunktzahl der Bowling-Runde durch die Gesamtpunktzahl jedes Frames berechnet. Die Berechnung jedes Frames ist trivial und so mussten nur noch diese Teillösungen zur Gesamtlösung komponiert werden, d.h. die Summe der Frames musste berechnet werden. Diese Gedanken helfen beim Problemlösen enorm.</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Thu, 13 Aug 2009 15:38:00 +0200</pubDate>
            <category>haskell</category>
            <category>theorie</category>
            <category>verifikation</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-5</guid>
            <title>Linktipps #5</title>
            <link>http://blackflash.nordic-dev.de/linktipps-5</link>
            <description><![CDATA[<p>Bei diesem Mal geht es nur um empfehlenswerte Artikel, die sich mit CouchDB befassen.</p>
<ul>
<li><span><a target="_blank" href="http://johnpwood.net/2009/06/15/couchdb-a-case-study/">CouchDB: A Case Study</a>: Es werden einige Gründe dargelegt, in welchen Fällen und weshalb CouchDB eine interessante Alternative zu RDBMS ist.<br></span></li><li><span><a target="_blank" href="http://johnpwood.net/2009/06/30/couchdb-databases-and-documents/">CouchDB: Databases and Documents</a>: In dem Artikel wird in die Terminologie von CouchDB eingeführt und wesentliche Eigenschaften erläutert. </span></li><li><span><a target="_blank" href="http://johnpwood.net/2009/07/10/couchdb-views-%E2%80%93-the-advantages/">CouchDB: Views – The Advantages</a>: Eine Erläuterung über die Stärken der Views von CouchDB und natürlich einige Beispiele, wie diese Views funktionieren.<br></span></li><li><a target="_blank" href="http://johnpwood.net/2009/07/21/couchdb-views-the-challenges/">CouchDB: Views – The Challenges</a>: In diesem Artikel werden Probleme aufgezeigt, die durch Benutzung von Views entstehen können.</li><li><a href="http://johnpwood.net/2009/08/04/couchdb-application-changes/" target="_blank">CouchDB: Application Changes</a>: John P. Wood erklärt die notwendigen Änderungen an der Applikation, um CouchDB ins Projekt zu integrieren. Entstanden ist eine sehr ausführliche Beschreibung dieser Migration.</li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 08 Aug 2009 11:13:00 +0200</pubDate>
            <category>couchdb</category>
            <category>datenbank</category>
            <category>links</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/mein-erster-artikel-auf-phphatesme-com</guid>
            <title>Mein erster Artikel auf phphatesme.com</title>
            <link>http://blackflash.nordic-dev.de/mein-erster-artikel-auf-phphatesme-com</link>
            <description><![CDATA[<p>Am Mittwoch ist <a target="_blank" href="http://www.phphatesme.com/blog/akademischer-tag/regulaere-ausdruecke/">mein erster Artikel auf phphatesme.com</a> im Rahmen des <a target="_blank" href="http://www.phphatesme.com/archives/category/akademischer-tag/">Akademischen Tags</a> erschienen. Das Thema waren reguläre Ausdrücke, worüber ich bereits vor einiger Zeit einen <a target="_blank" href="http://blackflash.nordic-dev.de/theorie-ueber-regulaere-ausdruecke">Artikel</a> verfasst hatte. Diesmal ging es jedoch noch mehr um die Theorie, da dies mein wichtigstes Anliegen war, die Grundlagen verständlich zu machen, sodass man auf diesen aufbauen und noch interessantere Themen behandeln kann. Ich hoffe auf viele weitere solcher Artikel mit solchem Feedback. :-)</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Fri, 31 Jul 2009 11:59:00 +0200</pubDate>
            <category>php</category>
            <category>theorie</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/mengenpackungen-und-ferienwohnungen</guid>
            <title>Mengenpackungen und Ferienwohnungen</title>
            <link>http://blackflash.nordic-dev.de/mengenpackungen-und-ferienwohnungen</link>
            <description><![CDATA[<p>Dieses Mal geht es um ein scheinbar kleines Optimierungsproblem: Mich hat die Frage umtrieben, ob es möglich ist, einen effizienten Algorithmus zu entwerfen, der eine optimale Auslastung bzw. den maximalem Gewinn einer Ferienwohnung bestimmt. Das erste Problem, das es zu lösen gilt, ist das Finden eines geeigneten Formalismus. Nach ein wenig erfolglosem Rumprobieren mit Graphen und Recherche im Internet habe ich einen sehr geeigneten Formalismus gefunden, mit dem ich das Problem genau definieren kann:</p><ul><li>Voraussetzung: Alle Anmeldungen sind bereits im Voraus bekannt.</li><li>Eingabe:</li><li><ul><li>Die Mengen S<sub>1</sub>, ..., S<sub>n</sub>, die jeweils eine Anmeldung darstellt und die Tage, an denen die Ferienwohnung gebucht werden soll, enthält.</li><li>Eine Abbildung f: {1, ..., n<sub></sub>} &#8594; N, die jeder Anmeldung seinen jeweiligen Preis zuordnet.</li></ul></li><li>Ausgabe: Eine Menge von Indizes I&nbsp;&#8838; {1, ..., n} mit folgenden Eigenschaften:</li><li><ul><li>Für je zwei unterschiedliche Elemente i, j &#8712; I sind die Mengen S<sub>i</sub> und S<sub>j</sub> disjunkt.</li><li>Die Summe &#931;f(i) aller i &#8712; I ist maximal. </li></ul></li></ul><p>Diese Definition entspricht bis auf den Wortlaut der Definition des <a target="_blank" href="http://de.wikipedia.org/wiki/Mengenpackungsproblem">Mengenpackungsproblems</a> in seiner gewichteten Optimierungsvariante. Da dieses Problem <a target="_blank" href="http://de.wikipedia.org/wiki/NP-Vollst%C3%A4ndigkeit">NP-vollständig</a> ist, gibt es unter Annahme, dass <a target="_blank" href="http://de.wikipedia.org/wiki/P-NP-Problem">P &#8800; NP</a>, keinen effizienten Algorithmus zum Lösen dieses Problems. Jetzt wissen wir also, dass es keine algorithmische Lösung gibt, aber was bedeutet das? Das bedeutet, dass wir die (menschliche) Natur zum Lösen dieses Problems nutzen sollten: Jede Anmeldung wird möglichst schnell bestätigt und es wird eine Liste mit freien Tagen veröffentlicht. Zum einen bedeutet das, dass die Gäste mit sehr geringer Wahrscheinlichkeit abspringen, und zum anderen wird eine Selektion betrieben, sodass sich meist nur die Leute melden, welche die Ferienwohnung zu den freien Terminen mieten wollen. Zwar wird man dadurch i.d.R. nicht das Optimum erhalten, aber es ist eine ausreichend gute Approximation und steigert die Planungssicherheit sowie evtl. die Zufriedenheit der Gäste.</p><p>Und die Moral von der Geschicht? Man sollte nicht versuchen, alles mit dem Computer zu lösen, denn in vielen Fällen - vor allem im kleinen Maßstab - erhält man durch weitaus einfachere Methoden sehr brauchbare Ergebnisse.</p>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sun, 26 Jul 2009 12:02:00 +0200</pubDate>
            <category>theorie</category>
        </item>
        <item>
            <guid>http://blackflash.nordic-dev.de/linktipps-4</guid>
            <title>Linktipps #4</title>
            <link>http://blackflash.nordic-dev.de/linktipps-4</link>
            <description><![CDATA[Heute erscheint die vierte Ausgabe der Linktipps:<ul>
<li><a target="_blank" href="http://blog.sigfpe.com/2009/07/monad-for-combinatorial-search-with.html">A Monad for Combinatorial Search with Heuristics</a>: Der Artikel zeigt die Entwicklung einer Monade mit der man auch kompliziertere Backtracking-Algorithmen formulieren könnte. Basis hierfür sind Penalty-Listen durch die man Ansatzpunkte (für das Backtracking) priorisieren kann.</li><li><a target="_blank" href="http://horicky.blogspot.com/2009/07/choosing-between-sql-and-non-sql.html">Choosing between SQL and Non-SQL</a>: Ricky Ho beschreibt, aufgrund der zahlreichen Diskussionen über SQL vs. Non-SQL, einige wesentliche Aspekte von Anforderungen an Datenbanken, die sich jeder Applikationsentwickler vor Beginn eines Projekts stellen sollte.</li><li><a target="_blank" href="http://www.iis.sinica.edu.tw/%7Escm/2009/determining-list-steepness-in-a-homomorphism/">Determining List Steepness in a Homomorphism</a>: Ein Artikel für den theoretisch veranlagten Haskell-Entwickler, der interessante Zusammenhänge liefert und beweist. Für jemanden, der noch nicht in der Theorie steckt - so wie ich -, ist es auf jeden Fall eine angenehme Herausforderung, den Artikel zu verstehen.</li><li><a target="_blank" href="http://de.wikipedia.org/wiki/Karps_21_NP-vollst%C3%A4ndige_Probleme">Karps 21 NP-vollständige Probleme</a>: 21 Probleme, die man für eine <a target="_blank" href="http://de.wikipedia.org/wiki/Polynomialzeitreduktion">Polynomialzeitreduktion</a> gut verwenden kann - sehr nützlich.</li><li><span><a target="_blank" href="http://www.kingcrunch.de/blog/2009/07/23/setter-getter-public-zugriff-auf-attribut/">Setter, Getter, public? Zugriff auf Attribute</a>: Sebastian gibt eine kleine Einführung in die elementaren Möglichkeiten des Zugriffs auf Attribute (in PHP) und diskutiert diese anschließend.<br></span></li></ul>]]></description>
            <dc:creator>Blackflash</dc:creator>
            <pubDate>Sat, 25 Jul 2009 10:02:00 +0200</pubDate>
            <category>datenbank</category>
            <category>haskell</category>
            <category>links</category>
            <category>php</category>
            <category>theorie</category>
        </item>
    </channel>
</rss>

