Mer eksperimentering med PogoScript
Skriv en kommentar
I går skrev jeg en blogpost hvor jeg blant annet introduserte programmeringsspråket PogoScript. Dette språket fortjente litt mer eksperimentering, så jeg utvidet eksempelet litt, og har tenkt å vise det her.
Poenget med PogoScript – det som skiller språket fra alt annet jeg har sett – er at det enkelt muliggjør å skrive kode som nesten er normal engelsk (eller norsk for den del). Det er skjelden jeg ønsker å gå så langt som det PogoScript tillater, men om man får behov for å skrive kode som ikke-programmerer skal forstå, og man kan gjøre det i et språk som kompilerer til JavaScript, så er PogoScript en veldig interessant mulighet.
For eksempel kan jeg se for meg at man kan skrive enkelte forretningsregler i PogoScript. Et program skrevet i for eksempel C# for .NET kan så kompilere PogoScript-koden til JavaScript og eksekvere denne med med en interpreter (f.eks. Jint). Og hey presto: Du har et veldig fleksibelt system hvor forretningsfolk kan lese og forstå deler av koden, og til og med kan endre funksjonaliteten selv ved behov.
En DSLifisering av bowling-koden
Jeg har altså gjort et lite forsøk på å vise hvordan jeg kan gjøre koden min mere leselig for ikke-utviklere vha. PogoScript. Koden du får se beregner poengsummen for en bowlingserie. Den første funksjonen heter “total score for (game)”. game er parameteret til funksjonen – et array med de ulike kastene i serien.
total score for (game) =
result = 0
do the following once for every frame
result = result +
score of next frame in (game)
result
Les koden! “Do the following once for every frame”. “Result = result + score of next frame in game”. Dette er ganske enkelt å forstå – om man kan bowling. “score of next frame in (game)” er en annen funksjon, og den kommer her:
score of next frame in (rolls) =
if (first throw in (rolls) got all pins down)
take the first pin count in (rolls) +
the next two throws in (rolls)
else if (first two throws in (rolls) got all pins down)
take the two first pin counts in (rolls) +
the next throw in (rolls)
else
take the two first pin counts in (rolls)
Dette ser ut som en beskrivelse, som såkalt pseudokode, men det er faktisk eksekverbar kode. Er det ikke kult? En utvikler vil kanskje ikke synes det er så veldig leselig, men en som ikke kan programmering vil forhåpentligvis kunne sette pris på det.
De to funksjonene over kaller en rekke andre funksjoner, som utgjør det vi kan kalle en DSL – et domenespesifikt språk for domenet bowling. DSL-funksjonen skjuler de teknsike detaljene. Og her er de:
do the following once for every frame (block) =
for (i = 0, i < 10, i = i + 1)
block()
first throw in (rolls) got all pins down =
rolls.0 == 10
first two throws in (rolls) got all pins down =
(rolls.0 + rolls.1) == 10
take the two first pin counts in (rolls) =
rolls.shift() + rolls.shift()
take the first pin count in (rolls) =
rolls.shift()
the next throw in (rolls) =
rolls.0
the next two throws in (rolls) =
rolls.0 + rolls.1
Skulle jeg faktisk ha brukt dette her hadde jeg nok gjort meg mere flid med oppbygningen av DSL’en, men koden her illustrerer i alle fall noen av mulighetene.
Til slutt kan jeg laget en tilfeldig bowlingserie og beregne score. Selv disse to linjene er veldig leselige – jeg tror Donald Knuth (opphavsmannen til Litterær programmering) ville vært stolt.
random game = [10,8,2,5,5,7,3,10,10,7,1,10,10,10,10,8] console.log (total score for (random game))
Resultatet av dette skriptet er tallet 213.
Kategorier: DSL.
RSS feed for kommentarene.
Tilbaketråkk.
Programmeringsbloggen
September 26th, 2012 at 11:01 pm
Oi, det var annerledes. Morsomt språk, men som du sier tror jeg at utviklere fort føler seg mer desorienterte enn ikke-utviklere, siden det krever litt mer å skille på nøkkelord og funksjonsnavn.
Jeg tenkte: Den måten å ha “infix”-parametre minner litt om Smalltalk, synes du ikke?
September 27th, 2012 at 7:25 am
Jo, på en måte minner det vel om Smalltalk. “What is unique about Smalltalk is its funny method invocation protocol. Method arguments are listed positionally, like in C or Java, but they must be preceded by the parameter name, and aren’t delimited by parentheses.” (sitat)
I Smalltalk er det altså ikke det at du putter parametere hvor du vil i metodenavnet, men at navnene på parametrene er metodenavnet. Dette gir en lignende mulighet til å “bygge setninger”, men ikke like fleksibelt.
For eksempel kan man si noe sånt som:
person er et objekt. hasGivenName:andSurname: er metoden (en sammensetning av de formelle parametrene). “Tom” og “Jones” er argumentene.