Potion, ett objekt- och mixin-orienterat språk

Postad

Why’s Potion

Författaren, tecknaren, musikern, konstnären, och programmeraren Why the Lucky Stiff har under en tid jobbat med ett litet och snabbt språk som han döpt till Potion. Språket är inte på något sätt färdigt eller ens menat att tas på allvar, men jag tycker att det är roligt att experimentera med nya och annorlunda språk.

Mantrat bakom Potion

"Allt är ett objekt, men objekten är inte allt" samt tillägget "Oh, och allt är en funktion"

Vad är speciellt med Potion?

  • Potion kompilerar ner programmen till maskinkod
  • Det inkluderar en liten "generational near-exact garbage collector"
  • Det är två språk i ett: ett för kod, ett för data
  • Det består av färre än 10.000 rader C

Potion är inspirerat av språken Io, Ruby, OCaml, Lua, REBOL och C. I den ordningen.

Installation under Mac OS X

Först måste man installera Ragel och det gör man enklast genom MacPorts:

sudo port install ragel

Och sedan klonar man källkoden med Git:

git clone git://github.com/why/potion.git

Efter det kompilerar man koden:

make

Dags att skriva lite kod

Enklast möjliga

'Athega' print

Kommer helt enkelt att skriva ut strängen 'Athega' genom att man skickar meddelandet print.

Något lite roligare

loop: 'Athega' print.

I Potion startar man block av kod med kolon och avslutar med punkt. Kommandot loop kommer att inte helt oväntat loopa över blocket (en oändlig loop). Meddelandet print sänds till strängen 'Athega'. Strängar är objekt, som allt annat. De tar emot meddelanden. Meddelanden är separerade från objekt med mellanrum. (I de flesta programmeringsspråk använder man punkt för att separera meddelanden, här (precis som i Svenska) representerar punkt ett avslut på något.)

Listor

('kaffet', 'på', 'h21', 'rockar') at (2) print

Nu skriver vi ut strängen 'h21'. Allt inom parenteser är listor. Vi skickar meddelandet at. Alla listor har ett at meddelande som hämtar poster baserat på positionen i listan.

Notera att efter at meddelandet kommer det en till lista. (2) är ett argument till at. Den ser ut som en lista (och det är en lista,) men vi kallar den för ett argument eftersom den kommer efter ett meddelande.

Den funktionella sidan

minus = (x, y): x - y.
minus (y=10, x=6)

Här har vi en variabel som innehåller en funktion. Funktionen subtraherar y från x. I detta fall returneras -4. (Detta liknar hur nyckelordsargument fungerar i Lua och Python)

Den objektorienterade sidan

Person = class: /name, /age, /sex.

Person print = (): 
 ('Mitt namn är ', /name, '.') join print.

p = Person ()
p /name = 'Peter'

p print

En subklass

Developer = Person class (language): /language = language.

Developer print = ():
  ('Mitt namn är ', /name, ' och jag gillar ', /language, '.') join print.

u = Developer ('Ruby')
u /name = 'Peter'

u print

Licks

Till sist har vi Lick vilket är dataspråket jag nämnde tidigare. Men varför skulle man vilja ha två språk i ett? En anledning är att det kan vara svårt att uttrycka data i kod.

Genom att ha ett separat litet dataspråk kan man bygga trädstrukturer av godtyckliga element, ungefär som i HTML. (Man kan se det som kod som har blivit tolkad men inte exekverad)

[name (attr1='string', attr2=10) 'TEXT HERE']

Varje lick kan ha ett namn, en tabell med attribut och en lista med barn. Listan med barn kan även vara av någon annan datatyp. (tex nummer eller sträng)

Vidare läsning

// Peter