Recently in Declarative programming Category

Learn You a Haskell for Great Good!

learnyouahaskell.jpgWie schon $immer hat man nie genug Zeit sich seinen Hobbies zu frönen. Ein Hobby wäre z.B. in der programmiersprache Haskell zu programmieren. Nun bin ich über "Learn You a Haskell" gestossen, was eine recht abgedrehte Haskelleinleitung ist (kann man auch kostenlos online lesen). Ich denke damit sollte es jedem Spaß machen Haskell zu lernen. Zwecks Wiederholung überfliege ich das Buch derzeit und finde dass es hier mal erwähnt werden sollte, nachdem ich per aktuellem Linux-Magazin unter den Buchvorstellungen darauf aufmerksam geworden bin.


Programming in Haskell

Um meine Haskellkenntnisse wieder aufzufrischen (in den letzten 3 Monaten habe ich dort relativ wenig gemacht aufgrund anderer Dinge) habe ich mir das Buch Programming in Haskell von Graham Hutton gegönnt.

programminginhaskell.jpg

Es dient Prima als Nachschlagewerk. Wer allerdings keine Lust auf trockenes Lesen hat, der kann sich den darauf basierenden Video-Lectures zuwenden.

Lazy Evaluation in Standard ML

Standard ML benutzt, im gegensatz zu Haskell, "Strict Evaluation" und keine "Lazy Evaluation" als Auswertungsstrategie. Mithilfe von Lazy Evaluation lassen sich auf besonders elegnater Art und Weise unendliche Datenstrukturen behandeln (z.B. unendliche abzählbare Folgen (wie eine Liste von allen Paaren aller natürlicher Zahlen nat_paare oder eine Liste von allen Paaren aller natürlichen Zahlen außer 0 nat_paare_nicht_null).) In Sprachen mit Strict Evaluation läßt sich jedoch meist Lazy Evaluation emulieren wie z.B. im Folgenden anhand von ML demonstriert:

type 'a lazy = unit -> 'a;
fun force (f:'a lazy) = f ();
fun delay x = (fn () => x) : 'a lazy;

datatype 'a sequ = NIL | CONS of 'a * 'a sequ lazy;

fun first 0 s = []
  | first n NIL = []
  | first n (CONS (i,r)) = i :: first (n-1) (force r);

fun filters p NIL = NIL
  | filters p (CONS (x,r)) =
    if p x 
      then CONS (x, fn () => filters p (force r)) 
      else filters p (force r);

fun nat_paare () = 
  let
    fun from_pair (x,0) = 
      CONS ((x,0), fn () => from_pair (0,x+1))
    | from_pair (up,dn) = 
      CONS ((up,dn), fn () => from_pair (up+1,dn-1))
   in from_pair (0,0)
  end;

(* Test 
val test = first 10 (nat_paare ())
*)

fun nat_paare_nicht_null () =
  filters (fn (x,y) => x > 0 andalso y > 0) (nat_paare ());
  
(* Test
val test = first 10 (nat_paare_nicht_null ());
*)
Da Haskell bereits Lazy Evaluation eingebaut hat, geht es hier einfacher. Hier muss auch kein neuer Datentyp definiert werden, da Haskell-Listen bereits lazy sind.:

{- Just to make it look like the ML example -}
first = take
filters = filter

{- Implementation -}
nat_paare = from_pair 0 0
   where
      from_pair x 0 = [x,0] : from_pair 0 (x+1)
      from_pair up dn = [up,dn] : from_pair (up+1) (dn-1)

{- Test: 
first 10 nat_paare
-}

nat_paare_nicht_null = 
   filters (\[x,y] -> x > 0 && y > 0) nat_paare

{- Test: 
first 10 nat_paare_nicht_null
-}

Standard ML und Haskell #2

Lindig2.jpegNochmal ein kleiner Vergleich zwischen Standard ML und Haskell. Dieses Mal geht es um Funktionen höherer Ordnung. Die Syntax ist fast die Selbe. Jedoch Haskell ist ein kleines bischen weniger verbose. Hier sind 4 Funktionen, jeweils in einer Standard ML Version (oben) und in einer Haskell Version (unten):

fun make_map_fn f1 = fn (x,y) => f1 x :: y
make_map_fn f1 = \x y -> f1 x : y

fun make_filter_fn f1 = 
     fn (x,y) => if f1 x then x :: y else y
make_filter_fn f1 = 
     \x y -> if f1 then x : y else y

fun my_map f l = foldr (make_map_fn f) [] l
my_map f l = foldr (make_map_fn f) [] l

fun my_filter f l = foldr (make_filter_fn f) [] l
my_filter f l = foldr (make_filter_fn f) [] l
Die Haskell Syntax ist darauf optimiert so wenig Boilerplate Code wie möglich zu produzieren. Standard ML ist da allerdings auch nicht gerade schlecht (die Funktionen my_map und my_filter haben in Haskell und in SML quasi die selbe Syntax. SML benutzt lediglich noch das Schlüsselwort fun).

Die interaktive SML shell lässt zu Wünschen übrig. So versuch ich vergebens einen Befehl die aktuell geladene Datei erneut einzulesen. In Haskell (ghci) geht das z.B. mit dem Befehl :r (r für reload) wie folgt:

*Main> :r
[1 of 1] Compiling Main             ( temp.hs, interpreted )
Ok, modules loaded: Main.

Bei SML hingegen muss ich mit Strg+D den interaktiven Prompt verlassen und die Bash-Histoy benutzen um "sml meinesourcecodedatei.sml" erneut einzulesen. Zwar gibt es einen sml-Befehl eine Sourcecodedatei einzulesen, aber der ist zu lang um ihn jedes Mal erneut eingeben zu können (Mein sml hat auch keine History-Funktion).

Standard ML und Haskell

Derzeit erarbeite ich mir die Grundlagen der funktionalen Programmiersprache Standard ML (Studium - Fortgeschrittene Konzepte funktionaler Programmierung). Da ich schon ein bischen Haskell kann, konnte ich es mir nicht nehmen die Aufgaben auch in einer Haskell-Version zu implementieren. Wie man sieht sind sich SML und Haskell (zumindest bisher in den Grundlagen) sehr ähnlich. Allerdings ist die Syntax von Haskell an einigen Stellen etwas "fortgeschrittener". Es werden in Haskell insgesamt etwas weniger Schlüsselwörter (z.B. val, end, fun, fn...) und Kommas in der Syntax verwendet. Ausserdem gibt es in Haskell die (optionale) Möglichkeit die Typen einer Funktion explizit hinzuschreiben. Was leserlicher ist und zudem Programmierfehler vermeidet. Was ich bisher bei SML vermisse sind auch die sog. Pattern Guards die es in Haskell gibt. I.A. gefällt mir bisher Haskell besser als SML, u.A. auch da Haskell sich "pur funktional" schimpft während SML auch von imperativen Konzepte explizit Gebrauch macht. Aber soweit bin ich in SML noch nicht. Hier ein paar Funktionen in SML und in Haskell im Vergleich:

Standard ML:

datatype ''a multi 
  = EMPTY
  | ELEM of ''a
  | UNION of ''a multi * ''a multi

Haskell:

data (Eq a) => Multi a
  = Empty
  | Elem a
  | Union (Multi a) (Multi a) 
  deriving Show

Standard ML:

fun number (EMPTY) _ = 0
  | number (ELEM x) w = if x = w then 1 else 0
  | number (UNION (x,y)) w = (number x w) + (number y w)

fun test_number w = 
  number (UNION (
    EMPTY, 
    UNION (
      ELEM 4,
      UNION (
        ELEM 6,
        UNION (
          UNION (
            ELEM 4,
            ELEM 4
          ),
        EMPTY)
      )
    )
  )) w

Haskell:

number Empty _ = 0
number (Elem x) w = if x == w then 1 else 0

test_number w = 
  number (Union 
    Empty
    (Union 
      (Elem 4)
      (Union
        (Elem 6)
        (Union
          (Union
            (Elem 4)
            (Elem 4)
          )
        Empty)
      )
    )
  ) w

Standard ML:

fun simplify (UNION (x,y)) = 
    let fun is_empty (EMPTY) = true
        | is_empty _ = false
       val x' = simplify x
       val y' = simplify y
     in if (is_empty x') andalso (is_empty y')
        then EMPTY
       else if (is_empty x')
        then y'
       else if (is_empty y')
        then x'
       else UNION (x', y')
    end
  | simplify x = x

Haskell:

simplify (Union x y) 
    | (isEmpty x') && (isEmpty y') = Empty
    | isEmpty x' = y'
    | isEmpty y' = x'
    | otherwise = Union x' y'
  where 
    isEmpty Empty = True
    isEmpty _ = False
    x' = simplify x
    y' = simplify y
simplify x = x

Standard ML:

fun delete_all m w =
  let fun delete_all' (ELEM x) = if x = w then EMPTY else ELEM x
      | delete_all' (UNION (x,y)) = UNION (delete_all' x, delete_all' y)
      | delete_all' x = x
   in simplify (delete_all' m)
  end

Haskell:

delete_all m w = simplify (delete_all' m)
  where
    delete_all' (Elem x) = if x == w then Empty else Elem x
    delete_all' (Union x y) = Union (delete_all' x) (delete_all' y)
    delete_all' x = x


Standard ML:

fun delete_one m w =
  let fun delete_one' (UNION (x,y)) = 
      let val (x', deleted) = delete_one' x 
       in if deleted 
        then (UNION (x', y), deleted)
        else let val (y', deleted) = delete_one' y 
           in (UNION (x, y'), deleted)
          end
        end
      | delete_one' (ELEM x) = 
        if x = w then (EMPTY, true) else (ELEM x, false)
      | delete_one' x = (x, false)
      val (m', _) = delete_one' m 
    in simplify m'
  end

Haskell:

delete_one m w = do
    let (m', _) = delete_one' m 
      simplify m'
  where
    delete_one' (Union x y) = 
      let (x', deleted) = delete_one' x 
       in if deleted 
        then (Union x' y, deleted)
        else let (y', deleted) = delete_one' y 
             in (Union x y', deleted)
    delete_one' (Elem x) = 
        if x == w then (Empty, True) else (Elem x, False)
    delete_one' x = (x, False)

Xing-Gruppe "Deklarative Programmierung" gegründet

dec060dc3.54370_1.pngIch hab nun eine Gruppe auf Xing gegründet. Und zwar "Deklarative Programmierung".

Die deklarative Programmierung ist ein Programmierparadigma, bei dem die Beschreibung des Problems im Vordergrund steht. Der Lösungsweg wird dann "automatisch" ermittelt. Zu den deklarativen Programmiersprachen gehören:
funktionale Sprachen (z. B. LISP, ML, Miranda, Gofer, Haskell, Erlang)
logische Sprachen (z. B. Prolog) und einige mehr. Deklarative Programmierung unterscheidet sich somit von dem verbreiteteren Programmierparadigma der imperativen Programmierung.

Freue mich immer auf neue Mitglieder! (Auch personen die sich noch nicht mit der deklarativen Programmierung auskennen sind herzlich eingeladen).

Monadic Perl

Nach C++ hab ich auch etwas gefunden, wo Monaden in Perl implementiert wurden. Es funktioniert, aber in Haskell wirkt die Implementierung von Monaden noch etwas eleganter. Aber das Resultat kommt dem in Haskell recht nahe:

sub ev
{
    my $term = $_[0];
    if($term =~ /^$con/)
    {
        return Return($1);
    }
    elsif($term=~/^$div/)
    {
        my $numer=$1; my $denom=$3;
        return DO {
                    my $n <- ev($numer);
                    my $d <- ev($denom);
                    my $g <- tick();
                    Return( $n / $d );
                  }
    }else{die "Syntax Error: $term";}
}

Buch-Review: Funktionale Programmierung

Thumbnail image for 41QUtMNiIqL.jpgMittlerweile hab ich das Buch Funktionale Programmierung.: Sprachdesign und Programmiertechnik durch. Hier erstmal ein Quote von wlt158 @ Amazon:

Das Buch ist ordentlich geschrieben, aber die Thematik ist für Einsame, denn, auch wenn es wirklich spannend und zukunftssicher ist, man geht einen akademischen Weg, einen Einsiedlerweg, oder für Optimisten: einen Königsweg, denn die deklarative Programmiung, wozu die funktionale Programmiung ja gehört, ist einfach die Zukunft - da gibts kein Wenn und Aber. Doch man wird sich über dieses spannende Thema in keinem Zug und keinem Bus mit keinem einzigen Nichtspezialisiten unterhalten können, denn das, was da drin steht, blicken 99% der Menschen um einen rum definitv nicht. Geschweige denn der oder die Lebenspartner/in. Ausnahme: Man arbeitet in einer Spezialabteilung für funktionale Programmierung. Ihr mutigen Pioniere! Mein Kompliment für das Buch.

Ich bin NICHT der Meinung, dass deklarative Programmierung die Zukunft ALLEINE sein wird. Imperative Sprachen werden in der Zukunft auch weiterhin die Oberhand behalten. Allerdings werden imperative Sprachen von deklarativen Sprachen immer mehr beeinflusst werden. Fast alle modernen imperativen Programmierprachen haben bereits jetzt einen gesunden Anteil funktionaler (deklarativer) Sprachelemente enthalten. Z.B. gibt es in C++0x sowie C# bereits Lambda-Funktionen.

Die Zukunft wird vermutlich in den General Purpose Misch-Sprachen und in den Domain-Specific Sprachen liegen. Rein-Funktionale Sprachen, wie Haskell, werden immer ein Nischendasein leben. Allerdings wirds immer eine Daseinsberechtigung geben, da alleine der Community-Kreis groß genug sein wird.

Letztendlich kann ich Jedem, der sich für funktionale Programmierung etwas tiefer auseinadersetzen möchte, dieses Buch empfehlen.

Als nächstes steht bei mir nun "Programming in Prolog" an :)

I've mentioned this book once before.

wizard.jpgStructure and Interpretation of Computer Programs has been MIT's introductory pre-professional computer science subject since 1981. It emphasizes the role of computer languages as vehicles for expressing knowledge and it presents basic principles of abstraction and modularity, together with essential techniques for designing and implementing computer languages. This course has had a worldwide impact on computer science curricula over the past two decades.

You can find the online videos and the free online book right here. For the case the ftp servers are busy you can download them from my own pub ftp instead (ftp.buetow.org/pub).

New book about functional programming ordered

41QUtMNiIqL.jpg I've just ordered a new book (in german language) called "Funktionale Programmierung: Sprachdesign und Programmiertechnik " (in english "Functional programming: Language design and programming techniques"). This book is for people who know already a little bit about functional programming but want to dig deeper a little bit! It is demonstrating lots of stuff using functional programming languages such as Haskell and Opal.

Pages

Powered by Movable Type 4.35-en

About this Archive

This page is an archive of recent entries in the Declarative programming category.

Databases is the previous category.

DNS is the next category.

Find recent content on the main index or look in the archives to find all content.