Andenplads ved E-handelsprisen 2008 og FLOT fremskridt

by DotNetNerd 27. March 2008 21:25

Andenplads ved E-handelsprisen 2008

Idag blev e-handelspisen for 2008 uddelt, hvor byggecity.dk som vi har udviklet var nomineret, hvilket vi allerede var glade for. Derudover blev det til en flot 2. plads i kategorien nystartere. Det er et projekt vi fortsat ser frem til at arbejde videre med, og hvor vi har nogle spændende initiativer i støbeskeen, så at det allerede har fået sådan en erkendtlighed er bestemt en behagelig overraskelse.

FLOwerTracker

I fritiden skrider det desuden også fremad med mit FLOwer Tracker projekt, som har fået egne domæner på flowertracker.dk og flowertracking.dk. I samme ombæring blev sitet flyttet til min egen virtuelle server, som jeg er blevet rigtigt glad for (solarvps.com). Projektet som sådan er også blevet udvidet en anelse, med udvidede muligheder for data udtræk, så det begynder efterhånden at ligne et mere komplet produkt - selvom der er passer af udvidelser på vej.

JoelOnSoftware om browserkompatibilitet

Joel har igen begået et fantastisk blogindlæg, hvor jeg synes han virkelig rammer sømmet på hovedet. Denne gang er det omkring hele den her browser krigszone som vi udviklere står midt i, og alt for mange vælger at udtale sig om uden rigtigt at have forstået problemet. Indlægget kan læses her: http://www.joelonsoftware.com/items/2008/03/17.html

Tags:

F# og imperativ programmering

by DotNetNerd 19. March 2008 23:50

Som jeg tidligere har nævnt er en af de helt store styrker ved F# at det giver mulighed for at kombinere forskellige stilarter, og jeg skylder derfor at runde imperativ programmering, som nok i virkeligheden er den programmeringsform de fleste udviklere er bekendt med.

Imperativ betyder påbud og inden for grammatik er det den form at et verb vi på dansk kalder bydeform (eks. "syng!"). Imperativ programmering vil derfor sige programmering hvor ens statements går på "hvordan" en opgave løses, hvorimod funktionel programmering handler mere om "hvad" der skal gøres.

Selvom F# i udgangspunkt er et funktionelt sprog der søger at få folk til at bruge immutable datastrukturer, kan det nogen gange være mere intuitivt at arbejde med imperative statements som loop strukturer og mutable data. Der kan selvfølgelig også nogen gange være en masse performance at hente ved ikke at skabe en masse objekter men istedet blot ændre en værdi.

Looping and iterating over data

Et helt basalt loop ligner noget man kender fra andre sprog og ser ud som herunder.

let PrintValues1To10 =
  for i = 0 to 10 do
    printfn "Value: %d" i

PrintValues1To10

På samme måde kan man desuden skrive et while loop sådan her.

let PrintNamesAndCities =
  for (name, city) in [("Christian", "Odense"); ("Henrik", "Kerteminde")] do
    printfn "%s %s" name city

PrintNamesAndCities

Mutable data og while loops

While loops som man kender dem findes naturligvis også, men disse bruges oftest sammen med mutable data hvis man tænker over det. Et typisk scenarie er at man laver en udregning og gentager denne indtil en given variabel har en værdi der tilfredsstiller et eller andet boolsk udtryk. Et eksempel på anvendelse at et while loop og mutable data kunne eksempelvis være.

let PrintWhileLessThan10 =
  let mutable i = 0
  while (i<10) do
    printfn "Value: %d" i
    i <- i+1

PrintWhileLessThan10

Det ovenstående eksempel viser den mest brugte måde at arbejde med mutable typer, men ligesom man i andre sprog kan arbejde med mutable reference typer kan man også i F# ved hjælp af keywordet ref og operatorerne ! og :=. På den måde kunne ovenstående stump kode have været skrevet sådan her, med samme overordnede resultat.

let PrintWhileLessThan10 =
  let i = ref 0
  while (!i<10) do
    printfn "Value: %d" !i
    i := !i+1

PrintWhileLessThan10

Imperative collections

Udover de datastrukturer jeg har set på tidligere her på bloggen kan man desuden også arbejde med de collection klasser der findes i .NET frameworket, som er imperative af natur. Disse collections bruges på samme vis som du sikkert er vant til men System.Collections.Generic.List<'a> bruges normalvis via aliaset ResizeArray, som er standard i F# fordi det er mere sigende for hvad strukturen er beregnet til.

let names = new ResizeArray<string>()

for name in ["Jens"; "Frans"; "Erik"] do
  names.Add(name)

printfn "Navn: %s" names.[1]

Exception raising og handling

En anden karakteristisk egenskab det går igen i imperative sprog er exception handling. Selvom det bygger på den måde exception handling fungerer på i .NET frameworket fungerer det en smugle anderledes i F#.

Hvis man vil raise en exception kan det gøres sådan her:

raise (System.InvalidOperationException("Man kan jo ikke dividere med 0 vel!"))

Der findes dog også en generel måde at raise exceptions på ved at skrive eksempelvis sådan her.

failwith "Man kan jo ikke dividere med 0 vel!"

Som medfører at en Microsoft.FSharp.Core.FailureException kastes. Den findes også i en failwithf der tager stringformat argumenter ligesom printf.
Specifikt til argument exceptions er der en forkortet udgave der kaster en InvalidArgumentException.

invalid_arg "argument må ikke have negativ værdi"

På den anden side af hegnet skal man jo også kunne håndtere exceptions. Dette fungerer som en kombination imellem en try catch som de fleste kender den og et udtryk til pattern matching.

try
  raise (System.InvalidOperationException("Fejl nu bare"))
with
  | :? System.InvalidOperationException as err -> printfn "Grebet ud: %s" err.Message

Ellers hvis man ønsker at gribe alle exceptions kan det gøres sådan her.

try
  raise (System.InvalidOperationException("Fejl nu bare"))
with
  | err -> printfn "Message: %s" err.Message

Og finally findes naturligvis også til at sørge for at ressourcer disposes korrekt - og den ligner sig selv som man kender den.

try
  raise (System.InvalidOperationException("Fejl nu bare"))
finally
  printfn "Finally kaldt"

Man kan dog ikke kombinere disse som i andre .NET sprog da en try-with-finally konstruktion ikke er understøttet, idet det ikke findes i OCaml. Det man normalt gør istedet er at bruge enten en "use" binding eller et "using" scope istedet.

let WriteToFile() =
  use output = File.CreateText(@"data.txt")
  output.WriteLine("This is nice")

 eller som using

let WriteToFile() =
  using (File.CreateText(@"data.txt")) (fun output ->
    output.WriteLine("This is nice"))

 

Tags:

Who am I?

My name is Christian Holm Diget, and I work as an independent consultant, in Denmark, where I write code, give advice on architecture and help with training. On the side I get to do a bit of speaking and help with miscellaneous community events.

Some of my primary focus areas are code quality, programming languages and using new technologies to provide value.

Microsoft Certified Professional Developer

Microsoft Most Valuable Professional

Month List