Akronym for “What the fuck!”. I denne kategorien vil du finne skikkelig stygg kode og andre ting som har fått bloggens forfatter til å sperre opp øynene og si WTF!!!

Ropy

Tuesday, January 1st, 2013
2 kommentarer

Hva er dette her?

image

Det du ser over er kildekoden til et program. Språket som er brukt heter Ropy, og programmet skriver som seg hør og bør ut teksten “hello, world”.

Ropy er altså et programmeringsspråk. Et ganske lite et. Og ganske ubrukelig egentlig, selv om det strengt tatt er turing-komplett, og dermed like “kraftig” som alle andre språk. Faktisk er det et forsøk på å lage en type språk vi kaller for en turing tarpit:

Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.

Alan Perlis, Epigrams on Programming

Jeg lagde Ropy i løpet av et par kvelder i desember. Språket er mitt bidrag til desember-konkurransen på PLT Games (Programming Language Theory Games). Hver måned blir man bedt om å lage et nytt programmeringsspråk, og i den påfølgende måneden vil man kunne stemme på hvilket bidrag man synes er best for å avgjøre en vinner. Språkene skal bedømmes i forhold til innovasjon, kompletthet og hvor godt de følger det valgte temaet for den måneden.

Hvis du har fulgt denne bloggen en stund så vet du at det er én oppgave jeg alltid pleier å løse: Å finne summen av alle tall under 1000 som er delelige på 3 eller 5. Og her er løsningen i Ropy:

image

Ropy er et stack-basert språk. Programmet begynner å kjøre oppe til venstre, og følger så tegnene. Når programmet har flere steder det kan gå – når “tauet” deler seg – velges den første veien i klokkeretningen. Men hvis verdien øverst på stacken er “0″ velger den vei mot klokkeretningen. Med dette kan vi simulere både if og løkker.

Den erfarne leser vil se at Ropy er inspirert av Befunge, som jeg presenterte i julekalenderen 2011.

Ropy-tolkeren er skrevet i Ruby, og er på godt under 200 linjer. Du kan ta en titt på den her, og vil du teste den selv er det bare å laste ned. Du finner også en eksekverbar spesifikasjon som vil hjelpe deg å forstå hvordan språket virker.

Ropy community

Kort tid etter at jeg hadde gjort Ropy tilgjengelig på Github fikk jeg også en pull requestSteffen Hageland, kjent som etse, hadde utvidet språket. Så jeg er tydeligvis ikke alene om å være helt sprø :)

Her er et eksempelprogram skrevet av Steffen:

image

Jeg trenger din stemme!

Som sagt er Ropy laget som et bidrag til en konkurranse. Og da hadde det selvsagt vært gøy om jeg fikk noen stemmer. Alle kan registrere seg for å være med å avgjøre vinneren (du må ha en github-bruker), og hvis du vil gi meg eller Ropy litt “cred” på den måten blir jeg veldig glad.

Får jeg litt stemmer kan det kanskje inspirere meg til å delta flere ganger også. Kanskje det blir 12 egenproduserte programmeirngsspråk å presentere på bloggen i år?! I januar skal det konkurreres om å lage et språk som fokuserer på automatisert testing. Ideer mottas med takk!

De viktigste lenkene

Noen utvalgte bidrag fra PLT Games du kan ta en titt på:

  • Colossal – som gjør programmering om til et tekstbasert adventure-spill.
  • nb – utfører programmer gjennom å simulere planet-baner i verdensrommet.
  • Turtle Graphics – Klassisk Turtle, turing tar-pit style. Test ut her!
  • turipong – utfører programmer ved å simulere en pong-ball som spretter fra vegg til vegg.
  • Hugo – et språk som stort sett består av GOTO-statements, og som har en veldig morsom README.
  • Seeker – programmene er node-grafer.
  • wc3pl – et språk inspirert av Warcraft III
  • cyprus“modeled as chemical reactions happening within protocellular constructions, producing new chemicals”
  • Ape – et interessant, minimalistisk språk implementert i noen få linjer F# av en Microsoft-ansatt språk-nerd.

No ifs and buts

Sunday, May 13th, 2012
Ingen kommentarer

For noen dager siden hadde vi en ny CodingDojo i Bergen. Oppgaven denne gangen var å presse objektorientering til det ytterste og trene på polymorfi gjennom å skrive kode helt uten bruk av IF, SWITCH eller tilsvarende konstruksjoner. Er du interessert i bakgrunnen for denne øvelsen kan du ta en titt her på bloggen til professor Eugene Wallingford. Du bør også sjekke ut the Anti-If Campaign.

Jeg jobbet sammen med @Olsenius for anledningen. Vi brukte Ruby. Oppgaven vi forsøkte å implementere var en billett-automat. Desverre ble dette mer et eksperiment i hvilke Ruby-triks vi kunne missbruke for å unngå IF enn en trening i god objektorientering. Koden vi produserte er noe av det værste jeg kan huske å ha laget :)

Vi ble ikke helt ferdige – jeg måtte gå litt tidlig – men koden vi produserte er gjengitt i sin helhet nedenfor. Vi brukte TDD, men testene har jeg droppet her.

Ser du hvordan vi har oppfunnet et nytt pattern både for IF og for UNLESS (altså “not if”)?

10 # Monkey patch: Just adding a convenient sum-method to arrays
11 class Array
12   def sum
13     self.inject(0){|x, y| x + y}
14   end
15 end
16 
17 class TicketMachine
18   def initialize
19     @balance, @total = [], []
20     @printers = { "total=5" => ValidTicket.new }
21     @money_validators = { "-" => InvalidMoney.new }
22   end
23 
24   # Properties:
25   def balance; @balance.sum; end
26   def total; @total.sum; end
27 
28   # Lets user print his ticket,
29   # but raises an Exception unless @balance is 5 !!!
30   def print_ticket
31     @printers["total=#{@balance.sum}"].print
32     @balance = []
33   end
34 
35   # Lets user insert money into the machine
36   # Will raise exception if money is a negative number !!!
37   def add money
38     begin
39       @money_validators[money.to_s[0]].fail_if_valid
40       raise "INVALID MONEY"
41     rescue NoMethodError
42       @balance << money
43       @total << money
44     end
45   end
46 end
47 
48 class ValidTicket
49   def print
50     puts "THE TICKET"
51   end
52 end
53 
54 class InvalidMoney
55   def fail_if_valid; end
56 end

That’s all!

Befunge

Tuesday, December 20th, 2011
5 kommentarer

I 1993 satte Chris Pressey seg som mål å lage et programmeringsspråk som var vanskeligere å kompilere enn alle andre språk. Resultatet ble Befunge, et språk du aldri har sett maken til. Om du finner et praktisk bruksområde for Befunge så er du god, men språket er uansett underholdende, og stimulerer hjernen til å tenke tanker du aldri har hatt før.

Gjør deg klar for litt orntlig trylling med tekst!

Befunge

Befunge skiller seg klart fra alle konvensjonelle språk. Som Forth og Factor er det et stack-basert, men måten man skriver programmer på i Befunge er helt anderledes.

Et Befunge-program er et todimensjonalt grid. Alle kommandoer er representert ved ett tegn. Program-counteren starter på kommandoen øverst til venstre i kildefilen, og så beveger den seg normalt ett og ett tegn mot høyre. Men man kan bruke spesielle kommandoer for å endre retningen, og programmet vil i praksis bevege seg på kryss og tvers i 2D-verdenen som kildekoden representerer.

La det synke inn litt… Et program i et tradisjonelt programmeringsspråk er en sekvens med instruksjoner. Man kan hoppe fra sted til sted – f.eks. ved hjelp av metodekall – men i metodene er det igjen en vanlig sekvens med instruksjoner. I Befunge kan programmet bevege seg til høyre, til venstre, oppover og nedover. Instruksjonspekeren kan til og med gå ut over en av kantene i kildekoden, og dukke opp igjen på den motsatte siden!

Euler-oppgave 1

Jepp, du har sett det før: en algoritme for å finne summen av alle multipler av 3 eller 5 mindre enn 1000.

 1  9872***9- v    Euler Problem #1
 2        >   v
 3            :                   >\         v
 4            !
 5            _   v               |  :  \+   <$
 6                :
 7        -       3
 8        1       %               $
 9                !               .
10        ^  \:<  _  v            @
11                   :
12                   5
13                   %
14                   !
15             ^     _     v
16        ^                <  - By Torbjørn Marø

Ahhhhhh, what a rush!! Det var kanskje den kjekkeste koden jeg har skrevet til denne julekalenderen. Jeg utfordrer deg til å forsøke selv, for dette er både stimulerende hjernetrim og underholdende morro.

Når du har begynt å tenke stack-basert, og vært innom andre ett-tegn-baserte språk som Betterave, så er løsningen egentlig ganske “rett frem”. Det mest utfordrende er å holde orden på koden, å strukturere den riktig og godt.

Nedenfor har jeg forsøkt å forklare programmet gjennom et diagram. Diagrammet speiler strukturen i koden – sammenligner du dem så vil du begynne å se det.

befunge_fig1

Har du noengang spilt et spill hvor du må plassere objekter i et rom får å få en laserstråle eller en ball til å lyse/sprette fra start til mål? Befunge er mye av det samme. Du kan også sammenligne det med workflow-baserte systemer; jeg ser på Befunge som en enkel ASCII-basert versjon av Windows Workflow Foundation eller tilsvarende prosessdesigner-verktøy, bare med et litt begrenset sett med byggeklosser.

Algoritmen jeg har brukt er forresten den samme som den rekursive algoritmen jeg løste oppgaven med i Forth. Men i Befunge har jeg laget en visuell utgave. Med litt fantasi kan jeg se for meg hvordan programmet kjører rundt i koden og bygger opp stacken, før den slår alle tallene sammen og skriver ut svaret.

Hvordan komme igang

Esolangs-wikien gir deg en god introduksjon til språket og alle kommandoene du kan benytte. Det finnes en rekke tolkere til Befunge, skrevet i blant annet Python, JavaScript og Java. Selv har jeg brukt en kompilator skrevet i C, men jeg klarer av en eller annen grunn ikke å finne eller huske hvor jeg fikk den fra. Men om noen er interessert i den kan jeg gjøre koden tilgjengelig.

Betterave

Friday, December 16th, 2011
1 kommentar

Betterave er et såkalt esoterisk programmeringsspråk, sånn som Unlambda som jeg snakket om i luke 8, eller Brainf*ck som jeg skrev om tidligere i år. Men slapp av, det er ikke like grufullt som dem. Selv om Betterave ved første øyekast ser helt uforståelig ut, er det egentlig ganske enkelt. Så her har du et språk det er en stor sjangse for at du kan lære deg, og bruke til å imponere dine nerdevenner ;)

betterave

Betterave består av funksjonsuttrykk på samme måte som Lisp/Scheme. Språket har en prefix-notasjon, men ulikt Lisp slipper man alle parantesene – hver funksjon “vet selv” hvor mange parametre det har. Dermed kan man også trekke paralleller til Rebol, som egentlig fungerer på samme måte.

Litt kode

Og da skal du få se ditt første Betterave-program. Igjen finner jeg summen av alle tall under 1000 som er multipler av 3 eller 5. Siden ingen funksjoner i Betterave er lengre enn én bokstav får hele programmet fint plass på én linje:

 1 L-***83679N0S0[N+n1T+=0%n3=0%n5?>t0S+sn!|<nl].s

Enkelt, ikke sant? Du skjønte dette?

Som sagt, det er ikke så vanskelig som det ser ut – og å lære det er ganske givende. Mere givende enn å spille minesveiper eller soduku i alle fall, så da er det verdt tiden til de fleste av oss.

Selv om programmet kan skrives på én linje, så det ikke det. Ved å bryte det litt opp og legge på noen kommentarer tror jeg det skal være ganske enkelt å forstå hvordan det virker. Men du må vite et par ting først…

Tall

Det er ikke mulig å uttrykke tall som er større enn 9 i Betterave direkte. Når vi skriver 9 i koden er det egentlig en parameterløs funksjon som returnerer tallet 9, og siden ingen funksjoner kan bestå av mer enn ett tegn finnes det ingen 10-funksjon. Så hvordan lager jeg da for eksempel tallet 999, som jeg trenger for å løse oppgaven min?

Jo, jeg må regne litt! 8 ganger 3 er lik 24. I Betterave skrives det som *83. Altså funskjonskallet * (stjerne/multipliser) som tar to argumenter: resultatet av funksjonen 8 og resultatet av funksjonen 3.

Videre er 24 ganger 6 lik 144. Dette kan jeg nå uttrykke som **836. Og ganger jeg dette med 7, og trekker fra 9, så står jeg igjen med 999. Funksjonsuttrykket blir da –***83679.

Variabler

I Betterave har programmene tilgang til å bruke 27 variabler, en for hver bokstav i det engelske alfabetet. Stor bokstav, for eksempel A, er en funksjon som tar ett argument og lagrer argumentet som verdi i variabelen. Liten bokstav, for eksempel a, er en funksjon uten parametre, som returnerer verdien i variabelen.

Nå har du lært nesten alle tingene jeg har brukt i programmet du så i starten. Det eneste som manger er muligheter for å ta avgjørelser og å lage løkker.

Programflyt

Jeg har brukt to strukturer for programflyt i programmet mitt. Den første er [ xxx | yyy ]. Den fungerer sånn at hvis yyy er noe annet enn verdien 0, så hopper programmet tilbake til startklammen – altså [. Det er altså en veldig enkel do-while løkke.

Den andre strukturen er ? xxx yyy !. Denne fungerer sånn at hvis verdien av xxx er 0 så vil programmet hoppe til utropstegnet, og altså ikke evaluere yyy. Dette er altså en enkel if-setning.

Kildekoden med struktur og kommentarer

Hvis du har fulgt med skal du nå være i stand til å forstå det hele:

10 L -***83679       ~ storing 999 in L (limit)      ~
11 N 0               ~ setting N to 0                ~
12 S 0               ~ setting S (sum) to 0          ~
13 
14 [                 ~ loop                          ~
15   N +n1           ~ increment N                   ~
16 
17   ~ set T to the sum of the modulo tests          ~
18   T + =0%n3 =0%n5
19 
20   ? >t0           ~ if T is larger than 0         ~
21     S+sn          ~ add N to S (sum)              ~
22   !               ~ end if ~
23 |
24   <nl             ~ while N is less than L (limit)~
25 ]                 ~ end loop                      ~
26 
27 .s                ~ print value of S              ~

Jeg sa jo at det var enkelt!

Hvorfor bruke tid på Betterave

Du skal bruke tid på Betterave og andre esoteriske programmeringsspråk fordi det gjør at du må tenke. Dette er rett og slett problemløsning hvor du tvinges til å sette deg inn i et sett med regler, og hvor du må finne ut hvordan du får systemet disse reglene representerer til å gjøre noe for deg. Dette stimulerer deg og gir deg ferdigheter du som en utvikler behøver.

Dessuten er det gøy!!!

Hvordan komme igang

All informasjon du behøver om Betterave finner du på esolangs.org. Denne wikien er også en god kilde til andre, lignende språk du kan forsøke deg på.

Selve tolkeren til Betterave er skrevet i Ruby, og er ikke mange linjene. Jeg måtte modifisere den litt for at den skulle virke slik som jeg ønsket (dvs. at den kunne ta en betterave-fil som et argument og så kjøre denne), og min versjon finner du her. Har du Ruby installert allerede er det bare å lagre ned koden, og så kan du kjøre betterave-filer ved å sende dem til tolkeren i kommandolinjen din.

Unlambda

Thursday, December 8th, 2011
11 kommentarer

“The effect of reading an Unlambda program is like having your brains smashed out by a Lisp sexp wrapped around an ENIAC. You won’t find anything like it west of Alpha Centauri.” – The Hitch-Hacker’s Guide to Programming

unlambda

Unlambda beskrives som et mareritt som har blitt virkelig. Det er med vilje designet for å gjøre programmeringen vanskelig og smertefull – eller utfordrende og underholdende, om du lærer deg å like denslags. Å skrive Unlambda-kode er vanskelig, men å lese Unlamdba-kode er praktisk talt umulig!

Det dreier seg her om et funksjonelt programmeringsspråk ala Scheme. I slike språk utgjør funksjonen den viktigste byggestenen, og i Unlambda er funksjonen faktisk det eneste man har å jobbe med. Matematisk kan man si at kjærnen i Unlambda er en implementasjon av Lambda Calculus, men uten selve Lambda-operatoren.

Unlambda er altså ikke ment å være et praktisk anvendelig språk. I stedet demonstrerer det svært ren, funksjonell programmering. Man kan ikke ha variabler, og har ingen vanlige operatorer eller datatyper. Alt man har er noen få innebygde funksjoner som hver tar én annen funksjon som parameter, og returnerer en ny funksjon. For å gjøre det ekstra kryptisk (og elegant) består hver funksjon av kun et tegn. Språket har ingen syntaks utover dette.

Hvorfor skal man bruke tid på Unlambda?

Det som skremmer meg med Unlambda er at det er et språk jeg sålangt ikke klarer å forstå. Jeg tror derimot at om man jobber litt med det, og begynner å skjønne hvordan man bruker det, så har man forstått noe svært sentralt innen funksjonell programmering. Man vil sansynligvis stå bedre rustet til å utføre små mirakler i Haskell, i Lisp-dialektene eller tilsvarende språk.

Har du først og fremst en praktisk tilnærming til programmering er altså dette språket sansynligvis ikke noe for deg. Men om du liker en utfordring, og har tro på at all kunnskap kan berike deg, så er Unlambda noe av det mest spesielle du kan lære.

Hvordan ser det ut?

Jeg beklager, men jeg har ikke klart å lage et program som løser Euler-oppgave 1. Men jeg tviler på at det har noe nå si. Følgende “lånte” Unlamda-program kalkulerer og skriver i stedet ut Fibonacci-tall i form av linjer med stjerner.

1 ```s``s``sii`ki
2   `k.*``s``s`ks
3  ``s`k`s`ks``s``s`ks``s`k`s`kr``s`k`sikk
4   `k``s`ksk

Som du ser er det mest brukte tegnet i dette programmet “backquote”. Dette er rett og slett Unlambdas apply-funksjon. S står for substitution, k kalles constant generator, og i er identity-funksjonen som bare returnerer sitt argument uendret. R skriver ut en ny linje, og .* skriver ut en stjerne.

Her ser du hvordan det ser ut når jeg kjører det med Java-implementasjonen av Unlambda (den fortsetter å kjøre i det uendelige antar jeg, men jeg trykket Ctrl-C for å stoppe den):

C:\unlambda-2.0.0\java>java unlambda.Execute fib.unl

*
*
**
***
*****
********
*************
*********************
**********************************
*******************************************************

Tar du utfordringen?

Siden jeg feiget ut og ikke klarte å løse den vanlige adventsoppgaven, så har vi jo egentlig en utfordring her. Kjempekudos til førstemann som poster løsningen i en kommentar!

hvordan kommer man i gang?

Det første man må gjøre er å lese det som står på den ofisielle websiden til The Unlambda Programming Language. Deretter kan man laste ned Unlambda versjon 2, som inkluderer implementasjoner i C, Java, Perl, Scheme med flere, samt eksempel-programmer og noen verktøy for Unlambda-utviklere. Og så er det bare å klø seg i hodet og forsøke å få ting til å virke :-)

"Rename method" kan være farlig

Friday, November 18th, 2011
3 kommentarer

Denne historien fra virkeligheten forteller om en tilsynelatende uskyldig og ufarlig refakturering som førte til at en katastrofal feil ble deployet til produksjon. Jeg har anonymisert og forenklet koden for å beskytte den skyldige (som var undertegnede selv) og for å gjøre det enkelt å forstå hva problemet er.

Det hele begynte med en nokså sentral klasse som vi skal kalle SomeBaseClass. Den hadde blant annet en metode vi for anledningen kaller DoSomething.

1     class SomeBaseClass
2     {
3         public void DoSomething()
4         {
5         }
6     }

Etterhvert som systemet vokste ble det innført mange klasser som arvet fra SomeBaseClass. En av disse var SomeDescendant.

1     class SomeDescendant : SomeBaseClass
2     {
3         public void DoIt()
4         {
5             DoSomething();
6         }
7     }

Alt fungerte som det skulle i lange tider, og alle var glade. Men så en dag fant en utvikler ut at han ikke likte navnet på metoden DoSomething. Heldigvis hadde han CodeRush-plugin i Visual Studio, og var derfor ganske sikker på at han raskt og trykt kunne endre navnet på metoden med den automatisert refaktureringen rename.

Utvikleren bestemte seg for at DoIt var et mye bedre og mere beskrivende navn!

Uheldigvis fungerte refaktureringen som den skulle. Koden kompilerte, testene var grønne, og endringen ble med i neste release. Utvikleren husket ikke at han allerede hadde kalt en av metodene i SomeDescendant for det samme.

10     class SomeBaseClass
11     {
12         public void DoIt()
13         {
14         }
15     }
16 
17     class SomeDescendant : SomeBaseClass
18     {
19         public void DoIt()
20         {
21             DoIt();
22         }
23     }

Ser du problemet? DoIt i SomeDescendant er nå en evig rekursjon.

Blir den kalt vil den føre til et stack overflow exception som det ikke er mulig å fange. Eller hvis JIT-kompilatoren har klart å optimalisere rekursjonen (TCO), noe jeg faktisk tror var tilfellet her, så vil programmet bare stå og spinne inn i uendeligheten eller til serveren brenner opp.

Bug retrospective

Burde denne feilen ha blitt oppdaget før release? Var det tankeløst å gjennomføre en sånn refakturering? Burde C# tillate denne koden i det hele tatt?

Jeg har alltid sett på rename som en veldig trygg refakturering i et IDE som Visual Studio og et statisk typet språk som C#, og de fleste av oss gjør det sikkert hele tiden. Navngivning er veldig viktig, og føler man at et navn er feil så bør man endre det.

Endringen førte derimot til at kompilatoren genererte en warning. Jeg har forsøkt å bruke “treat warnings as errors” opsjonen, men i praksis er det så mange “false positives” i større prosjekter at det å vedlikeholde alle unntakene blir en urimelig oppgave. Jeg tar manuelle gjennomganger av warnings fra tid til annen, men det er ikke rart at ting faller under radaren.

Vi kunne ha innført en kodestandard fra starten hvor vi alltid kalte metoder i baseklassen eksplisitt – altså base.DoIt() – men det ville også vært vanskelig å overholde.

Den eneste feilen jeg er villig til å innrømme var å ha for dårlig test coverage på koden! Hadde SomeDescendant.DoIt() blitt kalt i en test, ville problemet ha blitt oppdaget. Grunnen til at dette ikke ble gjort i tilfellet her var at DoIt i utgangspunktet var logikkløs, og at funksjonaliteten var blitt testet andre steder. Det føltes veldig trygt å ikke teste. Og det er alltid i slike tilfeller man angrer bittert i etterkant!

Det jeg sitter igjen med er likevel spørsmålet om C# burde tillate dette i det hele tatt. Som warningen sier: ‘SomeDescendant.DoIt()’ hides inherited member ‘SomeBaseClass.DoIt()’. Use the new keyword if hiding was intended. Hvorfor kunne ikke dette vært en error i stedet? Finnes det reelle tilfeller hvor “hiding” uten “new” faktisk kan være nyttig? En error ville gjort at jeg hadde oppdaget problemet og fikset det uten problemer.

Hvorfor ser alle websider om Common Lisp ut som om de ble laget i 1993?

Friday, July 15th, 2011
2 kommentarer

1363_delorean_time_machine

Er du klar for å hopp inn i tidsmaskinen og ta en titt på hvordan verden så ut for 15+ år siden? Slik føles det nemlig når du surfer rundt i Common Lisp (CL) -miljøet på nettet. Det er ganske fasinerende egentlig, og veldig, veldig merkelig.

La oss først ta et titt på en av de aller mest sentrale CL-sidene, nemlig CLiki – the common lisp wiki (screen shot under). Dette er faktisk et eksempel på en av de bedre sidene jeg har funnet; den er ganske ryddig og grei, men står litt tilbake for det jeg normalt forventer av en wiki.

cliki

Men la oss gå videre. Når man vurderer et programmeringsspråk er det viktig å se på selve communitiet, på brukergrupper og organisasjoner som fremmer brukernes interesser. Den sentrale organisasjonen i CL-miljøet ser ut til å være ALU – Association of Lisp Users (screen shot under). Hvilket inntrykk får du av denne websiden?

lisp.org

Hvis du ser helt nederst på skjermbildet der så ser du forresten at det jobbes med et nytt design for ALU og lisp.org. Jeg venter i spenning!

Det finnes mange ulike implementasjoner av CL. Den utgaven det ofte virker mest naturlig for nybegynnere å velge er GNU CLISP (screen shot under som vanlig), en gratis CL-implementasjon som kjører på mange platformer. Hvor komfortabel ville du være med å installere noe du fant på denne siden?

CLISP

Det er lenge siden jeg har sett HTML-tabeller med border=”15″, men på clisp.org mener man tydeligvis at hvis det var godt nok i 95 så bør det være godt nok i 2011.

Det finnes også en rekke komersielle CL-implementasjoner, men websidene deres er ikke så veldig mye bedre. Som en helt tilfeldig representant kan vi se på Corman Common Lisp (du klarer sikker finne screen shot’et selv fra nå av).

Corman 

Dette er altså hjemmesiden til et firma som lever av å selge en programmeringsplattform, og som selvfølgelig bør gi inntrykk av at de følger med i tiden. De har derfor innsett at de bør gjøre noe med siden, og har begynt på et nytt design…., som du ser nedenfor.

Corman2

Ok, de har fått seg farger, og viser nå at de er glade i graderinger. Og det er sikkert ubetydelig få brukere som får epileptisk anfall mens de ser på den.

Den gjennomsnittelige internettsiden om Common Lisp har minimalt med grafiske elementer, og minimalt med formatering. Man kan si at “Content is King” i CL-verden. Mange sider har ikke noen meny engang, absolutt alt man ønsker å si er bare spydd nedover forsiden. Et eksempel på dette finner man på siden til en av de mest kjente CL-webserverne, nemlig Hunchentoot.

hunchentoot

Legg merke til scrollbaren til høyre. Legg også merke til den fantastiske logoen. Det er ikke mange CL-prosjekter som har en egen logo, så Hunchentoot skiller seg faktisk positivt ut på det området. Selv om den ser ut til å ha vært designet i paint av en femåring er den ganske kul.

Slik flertallet av disse sidene er designet kan det nesten virke som om Common Lisp-utviklere ikke har oppdaget at grafiske brukergrensesnitt eksisterer, og at de stort sett surfer nettet via Lynx eller lignende tekstbasert browser. Men det må i alle fall være noen CL-utviklere som bruker GUI, for det finnes nemlig flere GUI-rammeverk for språket. McCLIM er et av dem.

mcclim

Det er ikke rart folk tror Common Lisp er et dødt språk når de ser websider som dette. Sammenlign denne siden med sider som omhandler f.eks. Adobe AIR. Hvilken platform blir du mest fristet til å velge?

Den neste siden jeg har funnet er en godbit for alle .NET-ninjaer: RDNZL (uttales “Redunzl”) er et biblotek som lar deg kalle .NET-kode fra Common Lisp. Jeg har testet det ut, og det fungerer utmerket. Men websiden er ikke spesielt imponerende. Legg igjen merke til scrollbaren.

RDNZL 

Selve rosinen i pølsen har jeg spart til sist. Common Lisp HyperSpec er hovedkilden til API-dokumentasj for CL-utviklere. Den har blant annet en “fantastisk” imagemap-basert meny, og designerne har tideligvis ikke vurdert søk som en viktig funksjon – søk finnes nemlig ikke. Anbefaler at du klikker på bildet og tar en nærmere titt på egenhånd…

hyperspec-front

Det har ikke vært meningen å henge ut folk i denne blogposten – det er mye bra innhold på disse sidene, og mange utviklere som har jobbet hardt og lenge med gode CL-løsninger. Men det må være lov å le litt av hvordan det hele presenteres.

Jeg sitter tilbake med en følelse av at noe bør gjøres for å løfte det generelle inntrykket folk får av Common Lisp på nettet. Jeg får lyst til å hjelpe til. Lyst til å lage en ny, moderne portal og inngangsport til språket. Forslag til konkrete ting vi kan gjøre mottas med takk!

Fiat lux

Thursday, May 26th, 2011
3 kommentarer

Det er ikke fredag i dag, men likevel, jeg gir dere “Universet, første alpha-versjon”

(ns genesis
    "Book of Genesis, 
    Version 0.0.1-SNAPSHOT")

; Some universal plumbing..
(def darkness 0)
(def light (inc darkness))
(def be identity)

; The main character..
(def God
     (fn [miracle something]
         (condp = miracle
             :create (symbol (name something))
             :see    (if (= something light) :good :evil)
             :say    (println "GOD:" something))))

; In the beginning
(defn in-the-beginning [darkness god]

   ; God created the heaven and the earth.
   (let [heaven (god :create :heaven)
         earth  (god :create :earth) ]
     (assert (and (= heaven 'heaven)
                  (= earth 'earth)))

     ; And God said,
     (god :say
          (pr-str
            ; Let there be light:
            (let [there (be light)]

              ; and there was light.
              (assert (= there light))

              ; And God saw the light,
              (assert (= (god :see light)
                         ; and it was good.
                         :good))

              ; And God divided the light from the darkness.
              (try (/ light darkness)
                   (catch java.lang.ArithmeticException ex
                          (god :say
                               (str "Ah, can't devide by zero, "
                                    "genesis postponed!")))))))))

(in-the-beginning darkness God)
;=> GOD: Ah, can't devide by zero, genesis postponed!
;=> GOD: nil
;=> nil

Brainf*ck

Saturday, May 14th, 2011
Ingen kommentarer

brainfuck_inofficial_logo

Vi utviklere er noen merkelige dyr av og til! Og det er når vi er på vårt aller mest merkelige at vi henter frem programmeringsspråk som brainfuck.

Brainfuck er ikke laget for å være praktisk; det er et fullverdig, Turing-komplett språk, men det er verken forståelig eller spesielt enkelt å bruke til noe fornuftig. Grunnen til at det i sin tid ble laget var at man ville se hvor liten man kunne få en kompilator. Oppfinneren Urban Müller klarte å lage en kompilator for brainfuck til Amiga OS som var på bare 240 bytes.

Jeg har lekt meg litt med brainfuck i det siste. Hvorfor det spør du kanskje? Tja, det er jo noe å lære seg.., en mental utfordring. Millioner av folk over hele kloden bruker jo timevis hver uke på å løse Sudoku – å løse oppgaver i et kryptisk programmeringsspråk er vel egentlig ikke så veldig mye mer spesielt?!

Jeg har til og med installert et integrert utviklingsmiljø for brainfuck – bfdev – hvor jeg kan steppe gjennom instruksjoner, inspisere program-minnet o.l.

bfdev_s

Men jeg har tatt det litt lengre enn som så også – jeg har nemlig implementert min egen brainfuck-tolker. På github finner du nå bf-clj som du kan bruke til å kjøre brainfuck fra Clojure. Igjen har jeg gjort dette fordi det var en mental utfordring.

Så veldig krevende var det heller ikke, men litt spennende å få til i et funksjonelt språk. Det er ikke alltid lett å finne små men utfordrende øvingsoppgaver man kan bruke til å trene programmering, men brainfuck kan i alle fall være en slik. Så jeg anbefaler alle å forsøke å implementere sin egen brainfuck-tolker.

Her har jeg laget en liten video som demonstrerer bf-clj…

Hva er galt med denne kanban-tavlen?

Saturday, November 13th, 2010
9 kommentarer

IMAG0160

Siste kommentarer

best seo services company
I'm not sure where you are getting your information, but good topic. I needs to spend some time learning more or understanding more. Thanks for wonder...
Louis Vuitton Outlet
30 years old Kalamazoo-born Vitalia totally likes it barbecuing bicycling. Last but not least she is intrigued by charters and flights as an example, ...
Børge Hansen
Denne likte jeg veldig godt. Du skriver godt og har gode betraktninger  Keep it up – flere trenger å tørre å lære mer om ledelse – du l...
Tormod
Er egentlig ikke overrasket. F# sin fortè er programmererens produktivitet/kvalitet og anledning til parallell kjøring. Men kjøremotoren har ...
Stian
Ville også prøvd med et større problem (x100 eller x1000 f.eks). Når man snakker så små brøkdeler av et sekund som her så kan tiden for en ell...
Torbjørn
Har ikke sjekket - tar en titt i morgen hvis tid :)...
Einar W. Høst
Mhp tco: hva sier ILSpy?...
Torbjørn
Har ikke sett noe på PSeq før, men kjenner til den typen funksjoner fra blant annet Clojure. Og problemet med slike funksjoner i sammenhenger som de...
Håvard
Veldig bra sammenligning! Har du sett på ytelsen av PSeq.* fra powerpakken? Tipper den vil gi performancehit på små mengder, men kan kanskje resul...
Torbjørn
Jeg kom på en demonstrasjon-variant til jeg burde inkludere, nemlig bruk av list comprehension (en type computation expression (også kalt monads)). ...
Creative Commons-lisens
Innholdet på denne bloggen er tilgjengelig under Creative Commons Navngivelse-Ikkekommersiell-DelPåSammeVilkår 3.0 Norge lisens.

Programmeringsbloggen
Kjempekjekt.com

© 2006-2013 Torbjørn Marø

Jeg har vært en profesjonell programmerer siden 1999, og dette er min blogg. Målet med bloggen er å stimulere meg selv og alle andre til kontinuerlig eksperimentering og læring.

Jeg forsøker å være allsidig, og programmerer blant annet i C#, Ruby, Erlang og Clojure.

Jeg praktiserer TDD og andre smidige utviklingspraksiser. Jeg er opptatt av kvalitet og ren kode.

Dette og ganske mye mer kan du lese om på denne bloggen!