1. Zertifizierung für Analytics und AdWords

    Zertifizierung für Analytics

    Es ist schon ein paar Tage her, da hatte ich die Idee mal meine Google-Zertifizierungen aufzufrischen. In den letzten Wochen hatte ich Anlass und auch ein wenig Zeit mich wieder mit Analytics und AdWords zu beschäftigen und habe nach und nach Zertifizierungen gemacht:

    • Google Analytics - Individuelle Qualifikation
    • AdWords Grundlagen
    • AdWords: Werbung im Suchwerbe-Netzwerk
    • AdWords: Mobile Werbung
    • AdWords: Videowerbung

    Zwei Dinge haben sich als nützliche Erkenntnisse erwiesen: Zum einen sollte man die Prüfungen unbedingt auf Englisch ablegen, da die deutschen Übersetzungen der Prüfungsfragen und -antworten teilweise schwer verständlich sind. Zum anderen ist es hilfreich die Zertifizierungen selbst als Teil des Lernprozesses zu verstehen. Die Zeit ist in der Regel reichlich bemessen und man hat genug Gelegenheit sich durch die Hilfe-Seiten und das weitere Material zu lesen.

  2. Irgendwann landet man immer bei der Philosophie

    Ein Kollege hat einen Abrisskalender mit interessanten und/oder lustigen Fakten. Wenn er der Meinung ist, dass einer der Sprüche des Kalenders für einen von uns interessant ist, hinterlässt er uns das entsprechende Kalenderblatt auf dem Schreibtisch. Auf diese Weise hat das Folgende den Weg zu mir gefunden:

    Steile These.

    Ist das wirklich so?

    Wie das folgende Jupyter Notebook zeigt: Ja, in der Tat. Die 95% werden nicht immer getroffen, aber die Zahl scheint schon sehr adäquat zu sein.

    Kurze Erläuterung, wie ich vorgegangen bin: Wikipedia hat eine spezielle Seite, bei deren Aufruf man einen zufälligen Eintrag aus der Online-Enzyklopädie erhält. Diese Funktion habe ich mir zu Nutze gemacht, in dem ich die Seite 500 mal aufgerufen habe. Jeder Aufruf hat dann den ersten Link (bereinigt, weil es ansonsten zu Problemen kommt) weiter verfolgt und von der dann folgenden Seite den ersten Link und von der und so weiter. Nach 100 Verlinkungen wurde die Suche als erfolglos abgebrochen. In den meisten Fällen ist man aber tatsächlich bei der Philosophie gelandet.

  3. Lua Programming and Game Development with Love2D

    Einen weiteren Kurs bei Udemy abgeschlossen: Lua Programming and Game Development with Love2D.

    Was soll ich sagen? Ich habe mich unheimlich gefreut als ich dieses Kursangebot bei Udemy gefunden habe. Ich habe schon seit längerem immer mal wieder Kleinigkeiten in Lua geschrieben und wollte mich intensiver mit LÖVE beschäftigen, habe aber nie einen richtigen Zugang gefunden. Das ist besonders frustrierend für mich gewesen, weil es als sehr leichtes Framework gilt.

    Aber wie das so ist: Wenn man einen guten Zugang findet, dann stellt es sich am Ende als gar nicht so wild heraus. Und genau diese Erfahrung hat mir der Kurs beschert. Da bekommt man direkt Lust einen 2D-Platformer zu schreiben.

    Das Spiel, das man im Verlauf des Kurses entwickelt.

  4. Data Science, Apache Spark & Python

    Heute habe ich den Udemy-Kurs Data Science, Apache Spark & Python: Analysiere echte Daten! abgeschlossen. Den Kurs kann ich rundheraus empfehlen, auch wenn er getrost in 1,5x Geschwindigkeit geschaut werden kann. Mit etwas Hintergrund in Funktionaler Programmierung sind die Konzepte von Spark schnell verstanden und anwendbar. Ein sehr mächtiges und nützliches Tool, auch wenn ich dafür in näherer Zukunft wohl leider keine Anwendung finde.

  5. Zertifizierung für mobile Websites

    Zertifizierung für mobile Websites

    Mir kam die spontane Eingebung meine AdWords-Zertifizierungen mal zu erneuern (ohne besonderen Grund), stattdessen bin ich bei dem Kurs für mobile Websites von Google hängen geblieben und habe nach dem Durcharbeiten des tatsächlich recht informativen Materials die Zertifizierung für mobile Websites abgelegt und bestanden. Yeah :)

  6. Ein Studium der Philosophie - Part 3

    Ein kurzer Zwischenbericht: Mit den Skripten zur theoretischen Philosohpie bin ich durch, nun folgt die praktische. Die Kurs-Hefte bisher waren sehr gut aufbereitet und enorm informativ. Ich habe ja bereits ein Studium der Philosophie absolviert, aber die erneute Lektüre von systematischen Darstellungen in den verschiedenen Themen-Bereichen hat mir geholfen einige "lose Punkte" in meinem Kopf zu verbinden.

    Eine etwas ärgerliche Sache ist dagegen die Organisation des Studiums an der FernUni: Vielleicht liegt es nur an mir, aber ich finde mich nur sehr schwer zu recht. Die Informationen sind über mindestens drei unterschiedliche Websites gestreut und es fällt mir schwer zu etwas definitive und verbindliche Auskünfte zu finden. Die Betreuung scheint eher mäßig zu sein (was etwas ungerecht ist, weil ich mich auch noch nicht sonderlich bemüht habe).

  7. Ein Studium der Philosophie - Part 2

    In den letzten Tagen kam Post: Die Studienhefte zu meinem Philosophie-Studium sind eingetroffen. In diesem Semester belege ich die Module Theoretische und Praktische Philosophie. In der Theoretischen Philosophie gibt es Kurse zur Logik, Sprachphilosophie, Erkenntnistheorie und Philosophy of Mind; in der Praktischen eine Einführung, Medizinethik, Aristoteles Nikomachische Ethik und Politik, sowie etwas zum Glück des Menschen und Kant. Insgesamt ein straffes Programm mit allein über 1.000 Seiten Skript, dazu noch einige weitere Lektüre. Ich bin gespannt, wie sich das Studium mit der Arbeit verträgt.

  8. How to decode union types in Elm

    Today I came across a problem regarding JSON decoding in Elm: How do you decode a string (e. g. nested in some object) to a union type in Elm? Say you have this

    someJsonString = 
      "{\"f\": \"Done\"}"
    

    and after decoding it should be this:

    type Status 
      = Done
      | Open
      | Failed
    
    type alias Stuff = 
      { f: Status }
    
    someParsedJson = 
      {f = Done}
    

    I was surprised to not find this covered in the Elm guide and while there are some Stackoverflow- and blog-posts on how to decode tagged unions, I found nothing about plain union types. So if you come across the same issue, here is the solution:

    statusDecoder =
      let
        statusHelper s =
          case s of
            "Done" -> Done
            "Open" -> Open
            _ -> Failed
    
      in
        map statusHelper string
    
    
    stuffDecoder = 
      map Stuff
        (field "f" statusDecoder)
    

    Find the whole example code in this gist and please let me know if there are other ways to tackle this problem.

  9. JavaScript 30 (Part 3)

    After almost three month I've finally accomplished to finish JavaScript30, a free course by Wes Bos. I learned a lot and I had a lot of fun on the way, so I can really recommend this course to everyone interested in JavaScript or client side web programming. I think I'll even take another course by Wes Bos about ES6, called ES6 for everyone. I am familiar with almost all topics covered, but I am quite sure that there are lots of small gems to discover.

    Additionally, to get a better grasp on modern JavaScript infrastructure, I today started a course called Building a JavaScript Development Environment by Cory House which is hosted on PluralSight.

  10. Logic Programming (Part 1)

    One of my goals for 2017 is to learn (more about) logic programming.

    As I recently noticed the great and famous Structure and Interpretation of Computer Programs contains a chapter dedicated to this topic. Instead of solving the exercises in the chapter with the language introduced in the book, I used Datalog in the Racket-flavour to tinker around. Datalog is a query language that is heavily inspired by Prolog (the grandfather of all logic programming languages), but only contains a limited (sub-)set of features.

    This gist contains my database as well as my solutions so far. I think I'll write more about Datalog later on as it is very interesting to compare it with sparql.

  11. Updating Elixir

    I just updated a small project I wrote in elixir almost four years (!) ago. The original project was written with elixir version 0.11.3-beta, the version currently installed on my laptop is 1.3.4 (although 1.4 is already available). The update went very smooth and I would like to document the steps necessary below:

    Pipes need parantheses

    It is not longer possible to write something like

    foo 1 |> bar 2 |> baz 3
    

    As the well written error message states: This "is ambiguous and should be written as":

    foo(1) |> bar(2) |> baz(3)
    

    HashDict and HashSet are no more

    The modules HashDict (HashDict.new/1 is undefined or private) and HashSet (HashSet.new/1 is undefined or private) are deprecated (and I think they are deprecated since version 1.1). Just replace every HashDict with Map and every HashSet with MapSet. As the APIs are almost the same as before this should work out very well.

    Remove "Behaviour"

    This (module Supervisor.Behaviour is not loaded and could not be found) is another no-brainer: Write

    use Supervisor
    # or
    use GenServer
    

    instead of

    use Supervisor.Behaviour
    # or
    use GenServer.Behaviour
    

    list_to_tuple

    Seems that the function list_to_tuple was removed from the elixir kernel-module (undefined function list_to_tuple/1). Instead just call the function from the erlang stdlib like this:

    :erlang.list_to_tuple([1,2,3])
    

    And except from some warnings this was all for me to move my little toy project from a very old to a new version of elixir. Nice.

  12. Functional Programming in Erlang

    Aktuell belege ich den Kurs "Functional Programming in Erlang" auf futurelearn.com. Der Kurs ist ein Einstieg sowohl in Erlang, als auch in funktionale Programmierung und fängt folgerichtig bei sehr einfachen Themen an: Was sind Module und Funktionen in Erlang? Wie verwendet man Rekursion? Wie Funktionen höherer Ordnung? Und wie kann man mit pattern matching und mehreren Funktionsköpfen auf if-then-else-Blöcke verzichten?

    Hier ein Beispiel aus einem von zwei "Assignments" (Assignment 1, Assignment 2) die während des Kurses angefertigt werden mussten und von Peers gereviewt wurden:

    bits(0, M) ->
        M;
    bits(N, M) ->
        bits(N div 2, M + N rem 2).
    
    bits(N) ->
        bits(N, 0).
    

    Die bits-Funktion nimmt eine Zahl und berechnet, wie viele 1en in der Bit-Repräsentation vorkommen. Wie zu sehen ist, kommen schon in diesem einfachen Beispiel gleich mehrere der oben genannten Konzepte zum Einsatz.

    Das ist alles in allem eine super Wiederholung. Erlang war die erste funktionale Sprache mit der ich mich beschäftigt habe, aber ich bin - wohl vor allem auf Grund der von Prolog beeinflussten Syntax - nie sehr warm mit ihr geworden. Daher habe ich mich seinerzeit dazu entschieden Elixir zu lernen (das war eine gute und erfolgreiche Entscheidung!).

    Nachdem ich nun nach einigen Jahren wieder zu Erlang zurückkehre muss ich feststellen, dass die Syntax gar nicht so schlimm ist: Mein anfängliches Unwohlsein ist wohl vor allem auf das Nicht-vertraut-sein mit funktionaler Programmierung zurückzuführen. Wenn man die Konzepte erst mal kennt, ist die Syntax kaum mehr ein Problem.

    Es gibt einen Folgekurs, der im April anfängt und sich mit den wirklich interessanten Aspekten von Erlang befasst: Stark nebenläufiger und verteilter Programmierung. Auch diesen MOOC werde ich mir ansehen und ich freue mich schon darauf.

  13. Process Mining with ProM

    Das wird ein kurzer Post: Ich habe gerade den Kurs Introduction to Process Mining with ProM bei FutureLearn abgeschlossen. Der Kurs war sehr kurzweilig, "hands-on" und das vorgestellte Framework und die Methodik zum Process Mining erscheinen mir sinnvoll und durchaus zukunftsträchtig.

    Aktuell sehe ich nur leider wenig Anwendungsfälle dafür und ich finde das Thema nicht hinreichend interessant, um es weiter zu verfolgen; sicher etwas, das man im Hinterkopf behalten sollte, aber mehr nicht.

  14. ClojureD 2017

    I already wrote a rather lengthy blog post on the Bob Konf, so I'll keep this one short: A day after Bob I attended this years ClojureD, a conference in Berlin (in a new, beautiful location) dedicated to the beloved LISP-dialect on the JVM.

    The talks I liked the most were "Writing Clojure at Runtime with Nightlight" by Zach Oakes, "The Elements of Style in Programming" by Bozhidar Batsov and "Making video games and learning Clojure" by Lisa Passing. I can warmly recommend to watch all these talks on Youtube as soon as the recordings are available. I think I will discuss the last one in greater detail on a later occasion as I plan to try some of the presented frameworks and libraries on my own.

  15. BOB2017

    Auch dieses Jahr hatte ich die Gelegenheit wieder die BobKonf in Berlin zu besuchen, die wieder einmal hervorragend organisiert war und ein breites und vor allen Dingen interessantes Spektrum an Themen bot. Hier eine kleine Zusammenfassung meines Konferenz-Tages:

    Why Functional Programming Matters (John Hughes)

    Eine hervorragende Keynote mit sehr vielen Leseempfehlungen. John Hughes hat diesen Vortrag schon bei einigen anderen Gelegenheiten gehalten, deswegen kann man ihn sich bequem bei Youtube anschauen, ohne auf die Aufzeichnung von der BobKonf warten zu müssen.

    The Future of Front-end Development: A Comparison (Alexander Thiemann)

    Alexander war letztes Jahr der Session Chair bei meinem Talk über Elm bei der Bob und wir haben uns vor und nach dem Talk ausgetauscht. Deswegen wusste ich, dass er Elm skeptisch gegenüber steht und war gespannt welche Alternativen er in seinem eigenen Talk vorstellt beziehungsweise wie sein Vergleich verschiedener Front-end Technologien ausfällt.

    Wenig überraschend fiel der Vergleich tatsächlich nicht zu Gunsten von Elm aus, stattdessen sieht Alexander das meiste Potential bei PureScript. Die beiden anderen vorgestellten Technologien empfehlen sich durchaus auch für bestimmte Anwendungsfälle: TypeScript, wenn man ein Team ohne funktionalen Hintergrund hat und GHC.js, wenn man sehr Haskell-orientiert ist und sich auf die durchaus nicht einfache Konfiguration zu Gunsten einer sehr umfangreichen Infrastruktur einlässt.

    Sehr schade fand' ich, dass im Vergleich einige Dinge gar nicht zur Sprache kamen: Was ist mit ClojureScript, BuckleScript, Fable und ReasonML? Wenigstens ein Ausblick wäre nett gewesen. Auf der anderen Seite wollte Alexander nur Dinge präsentieren, die er selbst schon in Produktion eingesetzt hat - was sehr löblich ist.

    Shell-Scripting mit Haskell (Franz Thoma)

    Franz Thoma hat einen guten Überblick über Shell Scripting mit Haskell gegeben. Besonders interessant daran ist, dass es auf der einen Seite eine hübsche Möglichkeit ist um Haskell anhand kleiner Projekte zu lernen, auf der anderen Haskell in Produktion (oder wenigstens für den internen Gebrauch) zu schummeln. Leider wurde ein durchaus nicht zu vernachlässigender Nachteil der Technik schon während der Präsentation deutlich: Die Scripte werden von GHC interpretiert, das heißt bei jeder Script-Ausführung hat man die Start-up Zeit von GHCi. Das macht sich leider negativ in der Ausführungsgeschwindigkeit bemerkbar...

    Functional Geekery hatte eine Episode in der der Autor der verwendeten Bibliotheken sein Werk und seine Motivation darstellt (hörenswert!).

    Immutable Hash Maps (Peter Schuck)

    Die Clojure-Implementierung von Datenstrukturen hatte und hat ziemlich großen Einfluss auf andere funktionale Sprachen und darf wohl weiterhin als state-of-the-art gelten. Dieser Vortrag hat dennoch gezeigt, dass weitere Verbesserungen hinsichtlich der Performance und der Code-Qualität möglich sind.

    Bayadera: Bayes + Clojure + GPU (Dragan Djuric)

    GPUs sind super in number crunching, aber unangenehm (weil low level-ig) zu programmieren. Dragan Djuric präsentiert in seinem Talk, wie man mittels der von ihm geschriebenen Clojure-Bibliotheken die Vorzüge von GPU-Programmierung nutzt, ohne die Schmerzen zu haben. Die Performance, die er damit erzielt, ist schon ziemlich beeindruckend.

    Definitiv ein Framework, das man im Auge behalten sollte (sofern man sich für High Performance Machine Learning interessiert).

    Functional package management with GNU Guix (Ricardo Wurmus)

    Dieser Vortrag war mein Highlight der Bob. Obwohl ich schon vorher von dem funktionalen Paketmanager Guix und der Skriptsprache Guile ("GNU Scheme") gehört hatte, war mir nicht klar, wie mächtig und cool diese Tools sind.

    Guix ermöglicht es nicht nur, dass man jederzeit einen bestimmten Stand von Pakten auf seinem Betriebssystem wiederherstellen kann, sondern auch das Anlegen von virtuellen Umgebungen: Ähnlich wie virtualenv in der Python-Welt, nur halt auf Betriebssystem-Ebene und für alle Arten von Paketen. Das Anlegen und Wechseln von Umgebungen ist einfach möglich.

    Auch das Anlegen von noch nicht vorhandenen Paketen (aktuell kennt die Verwaltung "nur" 4.500) ist einfach: Es gibt komfortabeles Tooling und die Konfiguration erfolgt in leicht lesbarem (!) Guile-Code. Wenn ich das Konzept richtig verstanden habe, kann man so auch beliebige andere Quellen, d. h. andere Paketmanager einbinden.

    Funktionale Programmierung in einer kleinen Firma (Raichoo Ketchum)

    Es ist viel einfacher sich hinterher zu entschuldigen, als vorher um Erlaubnis zu bitten.

    Raichoo Ketchum hat dieses Zitat von Grace Hopper angeführt und es fasst auch sehr gut seinen Vortrag zusammen: Um funktionale Programmierung durchzusetzen ist es manchmal das Beste einfach zu machen. In der Regel überzeugen die Ergebnisse, am Ende sind alle zufrieden unst es ist gar nicht nötig sich zu entschuldigen...

  16. Ein Studium der Philosophie

    Heute kam Post: Die Fernuni Hagen nimmt mich als Student im Master-Studium Philosophie an. Ich bin gespannt, ob sich das neben der Arbeit stemmen lässt und ob die Motivation noch einmal über 4 Semester (eher mehr) trägt. Das Studium selbst klingt spannend und bietet eine Menge interessantes Material.

  17. AEVO (Part 2)

    Am Dienstag hatte ich die schriftliche, heute die mündliche Prüfung für die Ausbildung der Ausbilder: Beide bestanden, nun darf ausgebildet werden.

  18. Tolkien und die lausavísa

    Den Herrn der Ringe lese ich traditionell alle ein bis zwei Jahre, seit ich 14 bin. Das heißt ich lese ihn gerade zum 10+ mal, ich kann es nicht ganz genau sagen. Immer wieder bin ich von der Sprachgewalt begeistert und bei jeder neuen Lektüre entdecke oder wiederentdecke ich etwas, was mir besonders gefällt oder mich begeistert.

    Am Wochenende war ich bei der Schlacht auf den Pelennor-Feldern (das ist das große Gefecht vor Minas Tirith) und mit einigem Erstaunen habe ich festgestellt, dass sich Tolkien hier mehrfach einem Mittel altnordischer Dichtung bedient, der lausavísa. Ich war weniger erstaunt, dass er es tut (die Bezüge und Anlagen an und in die nordische Mythologie und Literatur sind allgemein bekannt und unverkennbar), sondern das mir dieses Detail bisher vollkommen entgangen war.

    Auf dem Schlachtfeld lässt Tolkien Eomer zwei mal eine lose Strophe (das heißt lausavísa) aus dem Stehgreif sprechen und leitet sie formgereicht ein:

    Aber Éomer sagte zu ihnen:

    Nicht der Klage zu viel! Groß war der Gefallene Seiner würdig sein Tod. Wird ihm der Hügel geschichtet Mögen die Frauen weinen. Uns aber ruft der Krieg!

    Und später:

    Aus Zweifel und Finsternis kam ich, singend Mit blankem Schwert in der Morgensonne Ich ritt, bis Hoffnung und Herz zerbrachen: Auf nun! Dies ist der Tag des Verderbens!

    Diese Verse sprach er, doch lachte er dabei.

    In der Skaldik werden diese Gelegenheitsgedichte ebenfalls (d. h. wie bei Tolkien) im Fließtext einer literarischen Prosa-Erzählung (Saga) verwendet. Diejenigen, die sie sprechen, möchten einen Sachverhalt betonen, auf etwas hinweisen oder einen dramatischen Moment hervorheben. Wie in diesem Beispiel aus Egil's Saga:

    Then Egil spoke a verse:

    The slayer of the earl, unfearing ventured bravely forth in the thunder god's din bold-hearted Thorolf fell. The ground will grow over my great brother near Wen; deep as my sorrow is I must keep it to myself.

    Diese lose Strophe spricht der Kriegerpoet Egil anlässlich des Tods seines Bruders Thorolfs in der Schlacht.

    Bei allen drei Beispielen handelt es sich um Übersetzungen und man müsste in die Originale schauen (ich habe leider keine englische Ausgabe des Herrn der Ringe da), um zu schauen, ob sich weitere Merkmale skaldischer Dichtung finden, wie Stab- und Binnenreim. Im Falle von Egil bin ich mir sicher, bei Tolkien nur fast.

  19. Lazy, infinite sequences (Part 3)

    What else is great about our lazy, infinite sequences? They are composable! That means that you can use functions to combine sequences with other sequences or functions to get new sequences. That's a quite powerful feature.

    Before we dive into this topic, look at my redefined unfold-function, now called take:

    const take = function(fn, n) {
      return range(n).reduce(([fn, l], ele) => {
        const [s, t] = fn()
        return [t, [...l, s]]
      }, [fn, []])
    }
    

    It now works in terms of a reduce and not only returns the list of resulting values, but also the last recipe-function. So it is easily possible to continue at the last calculation next time you need new values.

    Back to composability: First we need some helper functions and streams to later check our new super powers. We create a predicate (for even numbers), something we can use in a map, as well as two streams for the natural numbers and the fibonacci sequence.

    const even = n => n % 2 === 0
    const inc = n => n + 1
    
    const n = nums(1)
    const f = fibs(0,1)
    

    If you have followed along and already studied Part 1 and Part 2 of this series it comes with no surprise how our functions to combine and create new sequences are defined. In case of the combine-function we take two sequences in, call them and get values for both out, as well as a new recipe for the next values. We combine the value into an array and return this array as our result. The next thunk is a call to combine with the newly created functions f1 and f2.

    const combine = (s1, s2) => () => {
      const [v1, f1] = s1()
      const [v2, f2] = s2()
      return [[v1, v2], combine(f1, f2)]
    }
    take(combine(n, f), 20)[1]
    // [[1, 1], [2, 1], [3, 2], ... ]
    

    Map and filter both take a sequence and a function. They use their function to manipulate the sequence: In case of map, the function is applied to the returning value.

    const map = (s, f) => () => {
      const [v, fn] = s()
      return [f(v), map(fn, f)]
    }
    take(map(n, inc), 20)[1]
    // [2, 3, 4, 5, ... ]
    

    In case of filter, only those values are returned which pass the truth test of the given predicate-function.

    const filter = (s, p) => () => {
      let [v, fn] = s()
      while(!p(v)) {
        [v, fn] = fn()
      }
      return [v, filter(fn, p)]
    }
    take(filter(n, even), 20)[1]
    // [2, 4, 6, 8, ... ]
    

    Next we'll look at a beast of a function called zip. It takes in a function and a arbitrary large (or small) number of sequences. For every request for new values it generates a value for every sequence and a new recipe for the next value. It then fills all values into the function zip was called with and returns this as the new value for the zip-sequence.

    This allows to combine a huge number of streams in literally every way you can think of.

    const zip = (f, ...args) => () => {
      const [values, next] = args.reduce(
        ([vl, fl], fn) => {
          const [v, fun] = fn()
          return [[...vl, v], [...fl, fun]]
        }, [[], []])
      return [f(...values), zip(f, ...next)]
    }
    
    const helper = (...args) => args.join(" - ")
    take(zip(helper, n, f, filter(n, even)), 20)[1]
    // ["1 - 1 - 2", "2 - 1 - 4", "3 - 2 - 6", ... ]
    

    Of course there are other and more higher-order functions to use on sequences, but I think this is enough for a start.

    Next time I'll look at how you can define and use lazy sequences in other languages and why (and how) they are useful in the real world.

  20. Universal Register Machine

    I just updated some old Elm code from 0.17 to 0.18. The code is used to simulate a Universal Register Machine, the gif below shows the addition of two numbers. If you would like to run your own URM-code just copy the code from the gist to elm-lang.org/try, change the program inside the Elm snippet and update the registers as you like.

    URM

    I sketched this program while I was listening to the presentation at ClojureD. I think it is a powerful and seldom recognized feature of Elm, that it is easy to visualize things, e. g. complex behaviors.

  21. Maybe.map2 to the rescue

    (I wrote the following blog post almost one year ago, but never published it. I think now – with my new website – the time has come...)

    These days I had a problem. I wrote this function:

    sliceSize : Int -> Int -> Int -> Float
    sliceSize slices min max =
      (max - min) / (toFloat slices)
    

    It takes an interval (given by min- and max-value) and a number of slices and than calculates the size of a slice. For example: If the value of min is 20, the value of max is 50 and the number of slices is three, the function will return 10. So far everything is fine.

    Say, this function is called by another function that calculates the min- and max-value from a list of values. My first attempt looked something like this:

    data : List Int
    data =
      [34, 98, 75, 40, 56]
    
    
    getSliceSize : Int -> List Int -> Float
    getSliceSize slices data =
      let
        min = 
          List.minimum data 
          |> Maybe.withDefault 0
        max = 
          List.maximum data 
          |> Maybe.withDefault 0
      in
        sliceSize slices min max
    

    This is not very elegant and while it is okay in this case, their might be other cases where it is not appropriate to choose 0 as default value for a min- or max-value.

    Time to rethink the problem and try something else. Second solution:

    getSliceSize' : Int -> List Int -> Maybe Float
    getSliceSize' slices data =
      case List.minimum data of
        Just min ->
          case List.maximum data of
            Just max ->
              Just (sliceSize slices min max)
            Nothing ->
              Nothing
        Nothing ->
          Nothing
    

    This behaves much better, but it looks awkward and is way too much typing. One thing that is different to the former solution is, that the return-type changed. It is not longer Float, but Maybe Float. This is okay and -- in fact -- a bonus: Now it is not longer implicit how to treat cases, where there is nor min-, neither a max-value. The calling code has to explicitly handle special (error) cases.

    I thought, there has to be a better solution, that is shorter and achieves the same. So I looked how this is solved in other languages (Haskell), because I thought that functions on Functors or Monads may be a solution for this. And while that is true, it is much easier to take a look into the Elm docs and what other functions the Maybe-module provides. The final solution:

    getSliceSize'' : Int -> List Int -> Maybe Float
    getSliceSize'' slices data =
      Maybe.map2 
        (sliceSize slices) 
          (List.minimum data) 
          (List.maximum data)
    

    There is no need to handle the Just's or Nothing's yourself, the Maybe.map2 (and of course there are map, map3, map4 and map5) does this for you: If one of the incoming values is Nothing than the result will be Nothing. Else the (Just) values for min and max are taken to compute the result.

    I was very happy when I figured out this elegant solution. I think this is not obvious when you start writing Elm code. If you think that this is not the best solution or if you have an even better one, than please leave a comment below.

  22. Lazy, infinite sequences with Generators

    I was curious how to implement the stuff from the last post of this series with generators (if you don't know what generators are or how to use them, there is a good introduction by Kyle Simpson). It is easier than I thought.

    This is my ones-function:

    function* ones() {
      while(true) {
        yield 1
      }
    }
    

    To actually run it, it is necessary to construct an iterator.

    const o = ones()
    
    o.next().value;
    // 1
    

    To mimic the behaviour of unfold you need something like:

    const unfold2 = function(gen, n) {
      let result = []
      for(let i = 0; i < n; i++) {
        result.push(gen.next().value)
      }
      return result
    }
    
    unfold2(o, 7)
    // [1,1,1,1,1,1,1]
    

    You may recognize that this code does not use recursion and looks much more imperative. That is true as I wasn't able to get a version with recursion running (if you know why that is, feel free to contact me).

    fibs now looks like:

    function* fibs() {
      let a = 0
      let b = 1
      while(true) {
        let _a = a
        a = b
        b = _a + b
        yield a
      }
    }
    
    const f = fibs()
    
    unfold2(f, 20)
    // [1, 2, 3, 5, 8, 13, 21, ...]
    

    So, to be quite honest, I like the thunked-version much more: It is nearer to my heart as it looks more functional and descriptive. I'm not particularly happy with this special new syntax, although you get quite fast used to it.

    The generator-version has one clear advantage: To calculate 1.000 numbers of the fibonacci series is almost 10x faster.

  23. AEVO (Part 1)

    Seit heute nehme ich bis zum Ende der Woche an einem Intensivkurs zur Vorbereitung auf die Ausbildereignungsprüfung der IHK teil.

    Haupterkenntnis des Tages: Das Lehrgespräch ist die Lehrmethode der Wahl, weil sie den Auszubildenden am Besten in das Geschehen integriert und dadurch neu Erlerntes verfestigt. Das Lehrgespräch ist das tastende Nachfragen, mit dem der Auszubildende (oder generell Lernende) bei seinem Vorwissen abgeholt und Stück-für-Stück zu einer neuen Erkenntnis herangeführt wird -- eine Methode die mehr als 2.000 Jahre alt und auch unter dem Namen Hebammenkunst oder Mäeutik bekannt ist. Manche Dinge ändern sich scheinbar nie...

  24. Lazy, infinite sequences (Part 1)

    The last two days I've continued the coursera course on programming languages by Dan Grossmann. I've finished the first two parts (A and B) last year, but wasn't able to continue with the last part because of reasons. The course offers an in-depth discussion of programming language concepts, a main focus is on the key differences of functional and object oriented programming.

    Current topic of the course is subtyping, but I had a lack of concentration and found it more interesting to play around with lazy, infinite sequences (a topic of part B). First I tried to implement them in Elm, but the type checker went nuts (which is - in fact - not surprising).

    So, why not try the same with JavaScript (ES6 or TypeScript)?

    But first things first: A lazy sequence is something, that is produced on demand and not up front. It is infinite because it contains a recipe to produce - in theory - a sequence of infinte length. It is possible to achieve the same effect with generators, but I chose to work with thunks instead. A thunk is an expression that is wrapped inside an anonymous function to prevent its evaluation.

    const example = () => 2 + 3
    

    Here, the value of 2 + 3 = 5 is not evaluated until you call the function.

    example()
    // 5
    

    To create an infinite sequence we need a thunk, that returns a tuple of a value and another thunk. This second thunk contains the recipe to create more value-thunk-tuples... recursion, you know? So, let's create the infinite sequence of '1's:

    const ones = () => [1, ones]
    

    In this case the first value is a '1'. What about our thunk-recipe to create more '1's? We know, that it should return again a tuple with a '1' and a thunk, that (if called) returns a tuple with a '1' and a thunk-recipe. We already know, how that should look like: It is our ones-function! That is why the second thing in our tuple is the ones-function (recursion...).

    Call it like:

    ones()[0]
    // 1
    ones()[1]()[0]
    // 1
    ones()[1]()[1]()[0]
    // 1
    

    Okay, thats hard to read and write and it would be much nicer to have a function, that gives us the first n values of the infinite sequence:

    const unfold = function(fn, n) {
      if(n == 0) return [] // 1
      const [s,t] = fn()  // 2
      return [s, ...unfold(t, n - 1)] // 3
    }
    

    This function takes two arguments, a thunk and a number n. We then (1) check if n equals zero. In this case there is nothing to do and we return an empty array. Otherwise (2) we call our thunk, which returns a tuple of a value and the thunk to create our next value-thunk-tuple. We decompose this tuple with destructuring. The function returns (3) an array, where the first element is the current value, the rest is a recursive call to unfold with the new thunk and n decremented. The crazy spread-syntax is just prepending s to the head of the list, so another way to write this is [s].append(unfold(t, n-1)) (in fact this is much faster).

    unfold(ones, 10)
    // [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    

    Unfold is a nice helper-function to check if our sequences work as expected. What else is possible? Let's create a simple function that is the infinite sequence of alternating a's and b's.

    const abs = () => ['a', () => ['b', abs]]
    unfold(abs, 7)
    // ["a", "b", "a", "b", "a", "b", "a"]
    

    What if we need an additional parameter, e. g. we would like to cycle through an existing array? The trick is to wrap our thunk into a higher-order function:

    const cycle = (arr) => () => {
      const [head, ...rest] = arr
      return [head, cycle(rest.concat(head))]
    }
    

    Here, the thunk is inside the function that takes the arr-parameter. The thunk itself unpacks the arr into head and rest. The head is the value of the returned tuple. The new thunk is a call to cycle, with a new list, where the head is appended to the rest.

    To create our initial thunk we need to call our cycle-function with a list.

    const dwarves = cycle(["thorin","balin","gloin"])
    

    Now it is possible to feed our dwarves into the unfold-function:

    unfold(dwarves, 9)
    // ["thorin", "balin", "gloin", "thorin", ...]
    

    To create a sequence of numbers from x to y it is necessary to create a wrapped thunk, too.

    const nums = (n) => () => [n, nums(n + 1)]
    unfold(nums(1), 20)
    // [1, 2, 3, 4, 5, 6, 7, ...]
    

    Of course it is possible to use more than one parameter for our outer function. How about the fibonacci series?

    const fibs = (a, b) => () => [a+b, fibs(b, a + b)]
    unfold(fibs(0, 1), 20)
    // [1, 2, 3, 5, 8, 13, 21, ...]
    

    At first this might be a little bit mind bending, but I hope the examples help to understand the underlying principle.

  25. Konzept

    Letztes Jahr habe ich einige Konferenzen besucht, neue Programmiersprachen gelernt, dazu und zu vielen anderen Themen Bücher gelesen und ich habe an MOOCs teilgenommmen, an sehr vielen MOOCs. Das ist die Liste derjenigen, die ich erfolgreich abgeschlossen habe (in wilder Reihung):

    • Programming Languages, Part A (Coursera)
    • Programming Languages, Part B (Coursera)
    • Introduction to the Internet of Things and Embedded Systems (Coursera)
    • The Data Scientist’s Toolbox (Coursera)
    • R Programming (Coursera)
    • Getting and Cleaning Data (Coursera)
    • Exploratory Data Analysis (Coursera)
    • Reproducible Research (Coursera)
    • Statistical Inference (Coursera)
    • Reason and Persuasion: Thinking Through Three Dialogues By Plato (Coursera)
    • Dog Emotion and Cognition (Coursera)
    • Data Mining with Weka (Weka MOOC)
    • More Data Mining with Weka (Weka MOOC)
    • Advanced Data Mining with Weka (Weka MOOC)
    • Introduction to Linked Data and the Semantic Web (futurelearn)
    • Social Media Analytics (futurelearn)
    • Ethical Cities (futurelearn)
    • Semantic Notation – The Next Big Thing in BI? (openSAP)
    • Functional programming with Clojure (MOOC.fi)
    • Software Architecture (FernUni Hagen)

    Dazu kommen die, die ich angefangen und abgebrochen habe, weil ich gemerkt habe, dass es mir zu anstrengend wird, das Thema mich nicht interessiert oder aus Zeitmangel. Mitgenommen habe ich eigentlich immer etwas.

    Neue Dinge lernen, mich mit Programmiersprachen, Text und Data Mining, Philosophie oder was mich gerade interessiert auseinander zu setzen, ist (könnte man sagen) mein Hobby und ich verwende sehr viel Zeit darauf.

    Ich rede nur nicht sehr viel darüber.

    Dass ich in meiner Freizeit MOOCs mache wissen nur sehr wenige Leute und fast niemand weiß genau, welche und wie viele. Ich selbst verliere gelegentlich den Überblick, in welchen Kursen ich gerade eingeschrieben bin und was ich dafür tun muss. Das ist etwas, dass ich dieses Jahr unbedingt ändern will.

    Ich will mehr zeigen und für mich aufarbeiten, was ich in meiner Freizeit mache und ich will darüber schreiben. Zum einen, damit ich selbst den Überblick behalte und auch nach einem Jahr noch nachvollziehen kann, womit ich mich beschäftigt habe und (ganz wichtig!) wie meine Fortschritte in einem Themen-Bereich aussehen. Außerdem möchte ich die Ressourcen, die ich gefunden habe und nutze, gerne offen legen und anderen zugänglich machen.

    Deswegen habe ich diese Website gebaut. Sie soll ein Platz sein um in kurzen Beiträgen darzustellen, was mich gerade beschäftigt, ein Projekt-Tagebuch sozusagen. Ich werde Beiträge überwiegend auf Englisch verfassen, aber auch einige in Deutsch (so wie diesen), insbesondere wenn es lange Posts werden oder das Thema kompliziert ist.

    Wie man sieht hat sich mein Interesse mit Anfang des Jahres von Programmiersprachen und Data Mining vorübergehend (?) in Richtung Game Art verschoben. Auch diese Wandel in meinen Interessen, die ich selber manchmal recht faszinierend finde, möchte ich anhand dieser Website nachvollziehbar machen.

  26. New Website

    Today I've created my new website (i. e. this website). I thought about using Wordpress, because their are tons of themes, it is easy to set up and super easy to write new blog posts. I ended creating my own minimalistic theme (which is in fact inspired by Steve Dekortes blog) for python Pelican. Pelican is a static page creation tool and it has all I've wanted: Easy to setup, super customizable, markdown blog posts.

  27. JavaScript 30 (Part 2)

    So far I've watched seven or eight JavaScript 30-tutorials and I think it is time for some first impressions. Long story short: The course is great and I enjoy it a lot. I've learned some nice new tricks:

    • I knew about the spreading operator before, but to see it in action helps to get a feeling for the use cases.
    • Same applies for destructuring. E. g. to flip vars you can simply use [fst, snd] = [snd, fst]
    • Template strings are available in many other languages like Elixir or Ruby. I hope for wide-spread browser support in the near future.
    • Document.querySelector isn't a new feature, but I've seldom used it and wasn't aware how handy it is
    • The Fetch API is a nice shortcut for gathering data.
  28. Intro to Pixel Art (Part 3)

    Experiment

    Für diese Szene habe ich zwei Abende gebraucht und bin ganz zufrieden mit dem Ergebnis. Mit diesem kleinen Projekt schließt der erste Themenblock des Kurses ab, als nächstes geht es mit Animation (auch spannend) weiter. Zeit für einen kleinen Rückblick auf das bisher Gelernte.

    Zunächst bin ich fasziniert, denn es gibt so etwas wie einen klaren Prozess und ein Vorgehen, um relativ schnell zu guten Ergebnissen zu kommen. Zunächst modelliert man das Objekt, das man abbilden möchte, mit einfachen, schwarzen Formen: Striche, Kreise, Recht- und Dreiecke. Anschließend wird modelliert, das heißt es werden an den richtigen Stellen Pixel hinzugefügt oder entfernt. Das Ergebnis ist eine Kontur beziehungsweise so eine Art Schattenschnitt.

    Im nächsten Schritt werden zunächst nur mit Graustufen und einer imaginierten Lichtquelle die Lichteffekte ergänzt (wie bei der Eule). Abschließend wird eine Farbpalette erstellt und die Objekte entsprechend der verschiedenen Farbabstufungen eingefärbt. Das Erstellen der Farben verläuft seinerseits recht mechanisch, indem Hue, Saturation und Value der Grundfarbe nach einem bestimmten Schema angepasst werden.

    Für die Szene oben wurden mehrere Objekte, die nach diesem Schema entstanden sind, auf verschiedenen Layern angeordnet. Als Hintergrund wurde ein weiterer Layer für den Himmel hinzugefügt.

    Dieses Vorgehen ist sicher nur eine Art Pixel Art zu fabrizieren und vermutlich nicht der Weisheit letzter Schluss. Aber das strenge Vorgehen und der klare Prozess helfen mir als Einsteiger ungemein. Die Ergebnisse sind eigentlich fast immer annehmbar, was gut für die Motivation ist und mich gerne weiter machen lässt.

  29. JavaScript 30 (Part 1)

    Today I've started with JavaScript30, a free online course on some intermediate and advanced features of JavaScript. The couse doesn't use any libraries or frameworks, it's just ES6 and modern browser APIs.

    To be honest, I have a love-hate-relationship to JavaScript. I hope to learn some new and shiny and cool things.

  30. Intro to Pixel Art (Part 2)

    Today I've learned about lightning and adding value (different shades of a color).

    I'm not super proud of my (grey scale) owl

    Experiment

    but the elk looks quite nice.

    Experiment

  31. Intro to Pixel Art (Part 1)

    I really like the aesthetics of pixel art, maybe because I played the good old Lucas Arts adventure games a lot. To produce pixel art on my own is a skill I would love to master (or at least be a litte proficient in). So I was happy when I discovered this course on Udemy, together with the new years offer of Udemy: Every course for only 10 €.

    The first thing you create is a pixel person:

    Experiment

    My aim was to make the pixel person look like Henry David Thoreau, as he is depicted on this comic cover.

  32. SVG Animation (Part 2)

    Today I've finished the rest of the course on SVG animation. I've created some nice social buttons (animation on hover)

    Social buttons

    as well as this useless but nice thing

    Experiment

    Learnings:

    • SVG animations are quite powerful
    • browser support isn't as good as expected. Only Chrome does everything right. Firefox has e. g. problems with SVG and the transform-origin CSS property
    • it's a technology to keep in mind to produce "WOW effects"
  33. SVG Animation (Part 1)

    Doing animations with CSS and SVG is quite fascinating. It is a relativly new technology with lots of potential and it uses many things I am already firm with (JS, CSS and SVG).

    I was quite happy when I found a free course on Udemy that teaches SVG animations. It is a short course with only two hours of videos, but a nice one. The focus of the course is to produce assets that could be used on a "normal" website, like animated buttons and logos.

    First exercise: An animated logo.

    My animated logo

    The basic logo is just a colored circle with white text, the font used is Googles Pacifico. Link to the Pen.

  34. About

    I visualize data at my job.

    I work at graphomate, where I design and develop applications for data visualization. At my job I use JavaScript (with d3.js), TypeScript and Elm, but sometimes also Java, C# and Python.

    I like simplicity.

    That's why I prefer Functional Programming most of the time, e. g. with Elm, Elixir and F#.

    I've created a couple of small Elm example applications (zozozombies [code], RegisterMachine [code], LunarLander [code], Particle [code], Maze) and a handful of libraries (numeral-elm, elm-sentiment, elm-trend, porterstemmer). I've talked about Elm at BOB2016 and am one of the organizers of Elmoin (GitHub, Meetup), the Elm Meetup for Hamburg and Schleswig Holstein.

    I like to mine text.

    Although in a front-end role at the moment, my background, expertise and interest is in text mining.

    I wrote my master thesis (with Elixir) on multi-label classification of scientific articles. My work led to two publications (ICSC15, K-CAP15) and was awarded with the "Prof. Petersen Preis der Technik".


    Twitter / GitHub / me@gregor.codes