Bastian FenskeMenü

Mit 16 Jahren Erfahrung als Software-Entwickler biete ich Ihnen die Entwicklung von
Web-Applikationen, sowie Beratung und Schulungen.
Ich habe einen hohen Qualitätsanspruch an meine Arbeit und verfüge über ein breit gefächertes Spektrum an Erfahrungen.

gra2p

gra2p steht für „graph to php“ und ist eine Programmiersprache, die ich derzeit aus Spaß an der Freud’ entwickle. Sie ist stark an die funktionale Programmierung angelehnt, ist statisch typisiert und kompiliert nach PHP. Einige Features:

Ein einfaches Beispiel:

 1{
 2  greet (target:String) -> (greeting:String)
 3
 4  ("Hello ", target) concatenate toUpperCase (greeting)
 5}

Hier wird eine Funktion mit dem Namen greet definiert (Zeile 2). Eine Funktion wandelt immer ein Tupel in ein aneres um. greet erwartet ein Tupel mit einem Feld (ein String, der hier target genannt wird) und gibt ein Tupel mit einem Feld (ebenfalls einem String, hier greeting genannt) zurück.

Der Ausdruck in Zeile 4 hat ein Tupel mit Eingangswerten ("Hello ", target) und ein Tupel mit einem Ausgangswert (greeting). Ein Ausdruck wird immer dann ausgeführt, wenn alle Einganswerte (also hier "Hello " und target) verfügbar sind. Das Ergebnis der Operation ist wieder ein Tupel und sein erstes Feld wird entprechend als greeting gespeichert. Sobald alle Rückgabewerte zusammen sind (in dem Fall hier nur der einer, nämlich greeting) und keine weiteren Operationen mehr möglich sind, werden diese zurück gegeben.

Die gleiche Funktion könnte man auch so schreiben:

 1{
 2  greet (target:String) -> (output:String)
 3
 4  ("Hello ", target) concatenate (temporaryString)
 5  (temporaryString) toUpperCase (greeting)
 6}

Theoretisch wäre auch diese Schreibweise möglich, aber der Compiler wird hier meckern, um eine gute Lesbarkeit zu gewährleisten:

 1{
 2  greet (target:String) -> (greeting:String)
 3
 4  (temporaryString) toUpperCase (greeting)
 5  ("Hello ", target) concatenate (temporaryString)
 6}

Als anonyme Funktion sieht das so aus:

 1{ ("Hello ", 0:target:String) concatenate toUpperCase (String) }

Parameter-Namen sind in dem Fall optional und können weg gelassen werden:

 1{ ("Hello ", 0:String) concatenate toUpperCase (String) }

Funktionen mit Nebeneffekten werden mit einem Ausrufezeichen markiert. Ein Ausdruck, der die Funktion greet benutzt, könnte also so aussehen:

 1{ ("World") greet print! () }

Ein Switch ist wie eine Funktion, gibt jedoch einen von mehreren möglichen Optionen plus je einem Tupel zurück. Beispiel für einen Switch:

 1{
 2  authenticate? (username:String, password:String) ->
 3    invalid (validationErrors:Dictionary<String, List<String>>)
 4    error (storageError:Unit)
 5    success (userId:Int, userName:String)
 6
 7  (username, password) credentialsValid?
 8    invalid (validationErrors)
 9    valid | (password) hashPassword (passwordHash)
10
11  (username, passwordHash) storage.storeUser!?
12    error | () unit (storageError)
13    success (userId)
14
15  (userId, username) session.storeUser! ()
16}

Ein Switch wird durch ein Fragezeichen gekennzeichnet (authenticate?). Mögliche Zweige sind hier invalid, error und success.

storage und session sind hier Service-Instanzen, die pro Applikation konfiguriert werden und dann in der Applikation zur Verfügung stehen (Dependency-Injection).

Die Pipe (|) ist ein Shortcut für das Zusammensetzen und wieder Auseinanderdröseln von Tupels.

Stand der Entwicklung

Die Sprache befindet sich in der Konzeptionsphase, wobei es eine Runtime gibt, die bereits recht viel Kompilat in PHP laufen lassen kann und Teile des Compilers sind auch bereits umgesetzt.

Das Ganze macht jedenfalls irrsinnig Fetz und ich bin gespannt darauf, wie sich damit arbeiten lässt.