Smalltalk


onsdag 14. desember 2011 Julekalender Polyglot SmallTalk

Det finnes en håndfull språk som har hatt en enorm betydning for utviklingen av programmeringsspråk generelt. Jeg tenker da på språk som Algol, Lisp og C. Et annet språk som vi er nødt til å inkludere er Smalltalk – utviklet av Alan Key og Dan Ingalls med flere ved Xerox PARC på 60/70-tallet.

smalltalk

Smalltalk har påvirket oss på fire hovedområder: For det første har det influert syntaksen og semantikken til mange programmeringsspråk som har kommet senere – de som vises i figuren nedenfor er kun et lite utvalg. For det andre var Smalltalk en prototype på en programmeringsstil jeg har snakket om tidligere som kalles message passing style – en viktig modell for god objektorientert programmering (det var Alan Key som "fant opp" OOP-begrepet).

For det tredje inspirerte brukergrensesnittet utviklingen av grafiske operativsystem. Vinduene i den første Macintoshen var så og si identiske med vinduene i Smalltalk-80, den første offisielle releasen av språket. Og til slutt har Smalltalks integrerte utviklingsmiljø inspirert utviklingen av det vi i dag kjenner som IDE'er; visuelle programmeringsverktøy med kodebrowsere, debuggere osv.

smalltalk_legacy

Smalltalk er et minimalistisk og elegant språk. Absolutt alt er objekter, og syntaksen er enkel og konsis. Som i Lisp finnes det ingen spesielle strukturer eller kodeord for å lage løkker eller ta avgjørelser – alt er kun metodekall, eller "sending av meldinger til objekter" som Smalltalkere sier.

Integrert utviklingsmiljø

Smalltalk skiller seg nok fra de språkene du har brukt før ved det spesielle utviklingsmiljøet. Man koder ikke Smalltalk i tekstfiler som så enten tolkes eller kompileres for å kunne kjøre programmet. Smalltalk er et program i seg selv, som kjører hele tiden. Objektene lever i minnet, og man kan bruke en utforsker til å studere dem og endre dem.

Når man avslutter Smalltalk lagres alt sammen i et image; vi sier at Smalltalk er et image-basert utviklingsmiljø. Du kan lagre flere images, som i praksis blir ulike versjoner av Smalltalk, hvor du har gjort forskjellige endringer i hver av dem. Når du starter opp laster du ett av disse, som da altså både er språket, utviklingsmiljøet og programmet ditt.

Versjonen av Smalltalk som jeg har brukt har i tillegg til diverse utforskere, debugger og lignende også integrerte tutorials, integrert enhetstesting (SUnit) og støtte for avansert refakturering.

Og nå er du sikkert klar for litt kode

Som forklart tidligere forsøker jeg å løse Euler problem nummer 1 i alle nye språk jeg tester ut – altså hvordan man finner summen av alle tall under 1000 som er multipler av 3 eller 5. Her følger min første løsning i Smalltalk:

 1 ((1 to: 999) select: [:x |
 2   ((x rem: 3) == 0) | ((x rem: 5) == 0)
 3 ]) fold: [:memo :x | memo + x].

Jeg oppretter først et intervall fra 1 til 999. Så sender jeg meldingen select: til dette intervall-objektet, og sender med en kodeblokk som argument. Resultatet er at intervallet filtreres og jeg står igjen med en kolleksjon av tall som er multipler av 3 eller 5. Til slutt sender jeg meldingen fold: til kolleksjonen med en ny kodeblokk som plusser tallene sammen.

Sammenlign dette med denne løsningen i Ruby:

2 (1..999).select {|x|
3   x.modulo(3) == 0 or x.modulo(5) == 0
4 }.reduce {|memo, x| memo + x}

Likheten bør være tydelig. Ruby er nok det språket som er nærmest Smalltalk i dag. Det er noen syntaksforskjeller, spesielt knyttet til hvordan man sender meldinger til objekter (med dot-operatoren i Ruby), men ellers er disse to løsningene egentlig helt like.

Etter å ha browset litt i objektene i Smalltalk klarte jeg å rafinere løsningen litt, og kom opp med dette:

 5 ((1 to: 999)
 6   select: [:x | (x isDivisibleBy: 3) or: (x isDivisibleBy: 5) ]) sum

Det viste seg altså at Number-objektene allerede hadde en isDivisibleBy-metode (oppdaget dette da jeg skulle til å lage den selv), og at Collection hadde en sum-metode. Generelt sett har Smalltalk et veldig rikt API som har blitt bygget opp gjennom mange år.

Om du ikke er helt komfortabel med denne koden fordi det skjer mye på en gang har jeg brytt det opp litt for at det skal bli enklere å fordøye. Nedenfor lager jeg to temporære variabler: filter og range. Og så løser jeg oppgaven steg for steg, før jeg til slutt skriver ut svaret i det såkalte Transcript-vinduet (mer om det snart).

10 | filter range |
11 range := (1 to: 999).
12 filter := [:x | (x isDivisibleBy: 3) or: (x isDivisibleBy:  5)].
13 range := range select: filter.
14 range := range sum.
15 Transcript show: range.

Mer om utviklingsmiljøet

Det finnes en rekke open source-versjoner av Smalltalk. Squeak er kanskje den mest kjente, og er mye brukt til undervisning. GNU Smalltalk er ikke et komplett Smalltalk-miljø, men tilbyr i stedet en mer tradisjonell tolker for Smalltalk-kode. Amber er en Smalltalk-implementasjon laget i JavaScript, og gjør mye samme nytten som CoffeeScript som jeg snakket om i en tidligere luke.

Jeg valgte derimot å bruke en Smalltalk som heter Pharo, som kjører på Unix/Linux, MacOS og Windows, og ser helt likt ut alle steder. Nedenfor ser du et screenshot av hvordan det ser ut i bruk. Det du ser er en slags desktop med flere vinduer. Vinduet øverst til venstre er et arbeidsområde hvor jeg har skrevet litt kode (løsningen på oppgaven vår). Under dette vinduet er Transcript-vinduet, hvor jeg skriver ut resultatet.

Vinduet til høyre er en klasse/objekt-browser: Her har jeg navigert meg frem til isDevisableBy-metoden på Number-klassen. Selve koden for metoden vises nederst. Her kan jeg også foreta endringer om jeg ønsker det.

SmallTalk_Euler

Smalltalk's grafiske brukergrensesnitt lar deg kommunisere med objektene dine på en mye mer direkte måte enn hva som er mulig i de fleste andre programmeringsspråk. Dette bør du oppleve!

Kulturkonflikt

Om du er en Java, C#, C++ –utvikler eller lignende så er Smalltalk-verden i konflikt med deg. Smalltalkerne sier det er de som driver med ekte objektorientering, C++ er ikke orntlig OO. Smalltalk var trolig også en viktig drivkraft og inspirasjonsskilde til den smidige revolusjonen for ca 10 år siden. Flere kjente Agile-forkjempere drev med Smalltalk, som for eksempel Martin Fowler, og Kent Beck, mannen bak TDD.

Smalltalk hadde sin storhetstid, men så tok det slutt. Kanskje det var det at de følte seg bedre enn alle andre? C++ dro i alle fall fra, og ble for en liten periode en defacto standard for objektorientering. Siden har andre språk som Ruby kommet til, og plukket opp igjen arven fra Smalltalk.

Så hvordan er Smalltalk forskjellig fra C++?

Vel, det er mange forskjeller. Smalltalk er dynamisk, C++ er statisk. Smalltalk er laget med utvikleren i fokus, mens C++ er sterkere knyttet til datamaskinen, og hvordan den fungerer. Men for å forstå Smalltalk er det spesielt to sentrale ting du må vite:

For det første: ALT ER OBJEKTER! Absolutt alt! C++ har mye som ikke er det; grunnleggende datatyper, klasser, kontrollstrukturer osv. Men i Smalltalk er alt bygget på samme lest, og samme hvor langt du graver finner du objekter.

For det andre: ALL KODE HAR ÉN FAST KONSEPTUELL FORM: object messageSentToIt. All koden du skriver i Smalltalk sender meldinger til objekter!

Og Smalltalkerne sier at hvis du ønsker å fortsette å kode i C++, eller Java, eller C#, så må du forsikre deg om at du aldri forstår hva disse to tingene betyr og innebærer. Hvis det begynner å gi mening for deg så må du slutte å lære deg Smalltalk med en eneste gang, for det finnes ingen vei tilbake :D

Er Smalltalk verdt å bruke tid på?

Ja, det er det. Smalltalk er historisk viktig, spesielt innenfor utviklingen av objektorientert tankegang. Utviklingsmiljøet er også fasinerende, og noe det er verdt å bruke tid på å forstå. Om du aldri kommer til å bruke Smalltalk til noe fornuftig, er det likevel berikende å se hvordan det fungerer.

Og om du liker det, men ønsker å bruke et mere levende språk som støttes av et aktivt community, så kan du jo gå over til Ruby etterpå!

Hvordan komme igang

Jeg foreslår du laster ned Pharo og bare fyrer det opp – ingen installasjon er nødvendig. I Pharo vil du finne en integrert, interaktiv tutorial som vil få deg så smått igang. Du kan også ta en titt på boken Pharo by Example, som kan lastes ned som PDF.

Lykke til!


comments powered by Disqus