Folien

Werbung
OCaml und F#
Silvio Feig, Martin Benedict
Was ist OCaml?
●
1996 entwickelt
●
funktionale Programmiersprache
●
●
mit objektorientierten und imperativen
Elementen
kompilierte und interpretierte Sprache
Hello World in Ocaml
print_endline „hello, world“
Entwicklungshistorie
OCaml Compiler und Interpreter
Was ist F#?
●
aus OCaml hervorgegangen
●
OCaml-Syntax
●
Zugriff auf .net-Framework möglich
●
Entwickler Microsoft
Hello World in F#
printfn „hello, world“
F# Compiler und Interpreter
Unterschiede OCaml und F#
• OCaml besitzt ein mathematisch orientiertes
Modulsystem, F# ein objektorientiertes
• F# besitzt keine Funktoren
–
Realisierung über Interfaces
• F# lässt keine doppelten Definitionen zu
• F# weniger striktes Typsystem
–
null-Wert vorhanden
–
Überladung möglich
–
dynamische Typprüfung und Umwandlung
Datentypen in OCaml
●
●
unit-type
●
für Funktionen mit Seiteneffekten (Beispiel später)
●
wie () in Haskell
●
wie void in C
primitive Datentypen
Datentyp
float
Beispiel
2.4
int
3
bool
true
char
'x'
string
"abc"
Unterschiede zu Datentypen in F#
●
Weiter in OCaml nicht vorhandene Datentypen
●
●
●
Byte, Int, Long, Single, Native Int, Decimal, Big
Number
unsigned Byte, unsigned Int
Umwandlung mit Typnamen
let myFloat = float 2
let myInt = int 2.4
Variablendefinition
●
●
●
Variablendefinition erfolgt mit let
definierte Variablen können keinen neuen Wert
erhalten, sie sind immutable
Definitionen können verschachtelt werden:
let z =
let x = 2 in
let y = 3 in
x + y;;
→ Codebeispiel
Operatoren
●
übliche algebraische Operatoren
+,-,*,/,%,**
●
bitweise Operatoren und logische Operatoren
●
In OCaml für float separate Operatoren z.B. /.
●
In F# Operatoren für alle numerischen
Datentypen nutzbar, aber nur für gleiche Typen
Funktionsdefinition
●
Funktionsdefintion erfolgt mit let
let square x = x*x
●
Lambda-Ausdrücke mit fun
let subhalf = fun x -> x-(x/2.0)
●
rekursive Funktion mit rec
let rec abc x =
…
abc
●
Funktionen sind Datentypen
z.B. val square : float -> float
Funktionen
●
Es existiert immer ein Rückgabetyp (unit ist
auch ein Typ)
●
Typinferenz erfolgt automatisch
●
kann beeinflusst werden durch casting
let myFunc (a:float) = …
●
Funktionen können geschachtelt werden
●
●
Rückgabe steht immer am Ende des
Schachtelungsblocks
Funktionsausführung erfolgt stets bei Definition
→ Beispiel
→ Codebeispiel
Ausgabe und Eingabe
F#
OCaml
Ausgabe
printfn "hello, "
●
output_string stdout "world\n"
die Ausgabefunktionen sind prinzipiell vom Typ string->unit
Eingabe
System.Console.ReadLine()
●
●
Nutzt das .net zum Einlesen
Funktion vom Typ: unit->string
input_line stdin;;
●
●
Liest von Input-Stream
Funktion vom Typ:
in_channel->string
→ Codebeispiel
Imperative Elemente und
Alternativen
●
Variablen können mit Schlüsselwort versehen
werden und sind dann änderbar.
F#
Schlüsselwort: mutable
● Zuweisung: <-
OCaml
Schlüsselwort: ref
● Zuweisung: :=
● Derefernzierung: !
●
●
let mutable x = 2
x <- 3
let x = ref 3;;
x := !x + 1;;
Imperative Elemente und
Alternativen
●
Konstruktion von for und while-Schleifen
sind möglich
while (F#)
while n <= 10 do
let sq = n * n
printfn "%d %d" n sq
n <- n + 1
●
●
for (OCaml)
for n = 1 to 10 do
printf "%d %d" n (n * n)
done;;
Alternativen sind mit if/then/else/elif
möglich
Bei Alternativen müssen die Typen nach then
und else übereinstimmen
→ Codebeispiel
Tupel
●
Definition in runden Klammern
let myTuple = (2,3,“abc“)
●
Klammern können auch wegfallen
●
Zugriff mit fst,snd auf Tupel der Größe 2
●
Verschiedene Datentypen in Tupeln möglich
Records
●
●
●
mit struct vergleichbar
vorher mit type festlegen
let banane = {
name = „Banane“;
farbe = „yellow“;
vitamine = [„a“;“b“]
}
→ Codebeispiel
Listen
●
Definition von Listen mit
●
●
●
:: - Verkettungsoperator (cons)
[a;b] - In geschweiften Klammern mit Semikolon
getrennt
@ - Verkettung von Listen (concat)
●
Immer der gleiche Datentyp
●
am Ende immer leere Liste a::b::[]
●
Liste ist unveränderbar
Arrays
●
●
●
Array sind Felder auf die indiziert zugegriffen
werden kann
arr.[2]
Inhalte des Arrays können modifiziert werden
arr.[2]<-“Kirsche“
Definition von Arrays
let myArray = [|2;4;6;8|]
Sequenzen
werden in geschweiften Klammen definiert
let range = seq { 0 .. 2 .. 6}
●
●
●
werden im Gegensatz zu Listen lazily berechnet
Umwandlung von List und Arrays in Sequenzen
und umgekehrt ist möglich und wird z.T. Auch
implizit durchgeführt
toList, ofList, toArray, ofArray
Rekursionsschemata
●
●
bekannte Rekursionsschemata map, fold, zip
jeweils für Arrays, Sequenzen und Listen
List.map (fun x -> x*x) list
Array.fold (+) 0 array
Seq.zip seq1 seq2
→ Codebeispiel
Types
●
●
●
●
Typen werden mit type definiert
objektorientiert mit member-Schlüsselwort,
Zugriff mit obj.<variable>
Definition von Methoden mit
obj.<methName>(<params>)
z.B. ein Binärbaum (im Beispiel)
Pattern Matching
●
Pattern Matching erfolgt mit match
●
Matching muss erschöpfend sein
●
auch komplexe Typen sind möglich
let firstElement elems =
match elems with
| h :: t -> h
| [] -> „none“
Pattern Matching
Quelle: Syme, Don: Expert F#
→ Codebeispiel
Lazy Evaluation
●
●
●
Verwendung mit Schlüsselwort lazy
Berechnung wird erst ausgeführt, wenn
Lazy.force <variable> aufgerufen wird
Unterschied zu Haskell, man muss selbst mit
force entscheiden, wann berechnet wird
Monaden
●
●
existieren in F# (Computation Expression) und
OCaml
z.B. in F# Maybe-Monade mit
Option.None/Option.Some, MaybeBuilder
auch mit Syntactic Sugar
maybe{
let x = 12
let! y= Some 11//maybe.Bind(Some 11, f)
return x+y
}
Pipeline-Operator (F#)
●
|> ist der Pipeline-Operator
gibt Ergebnis der letzten Berechnung an die
nächste Funktion
let (|>) x f = f(x)
●
getwebsite
|> findtitle
|> countcharacters
→ Codebeispiel
Currying und Closures
●
Currying ist auch in OCaml und F# möglich
●
Zerlegung von Funktionen in Funktionen mit 1
Parameter
let f x y = x * y
let fwithtwo = f 2
let result = fwithtwo 4
Currying und Closures
man kann sich Funktionen „bauen“ lassen
let giveFunction a =
●
let createdFunction (x:int) =
(x+a)*(x+a)
createdFunction
let func4 = giveFunction 4
let erg = func4 2
→ Codebeispiel
Exceptions
●
es können Exceptions auftreten
●
Werfen von Exceptions mit raise
●
Fangen von Exceptions mit try with
try
raise(Failure “A problem”)
with
| Failure s - > s;;
→ Codebeispiel
Nutzen des .net-Frameworks (F#)
●
●
Funktionen von Klassen sind nutzbar
In F# haben Funktionen und Funktionen
höherer Ordnung eine Entsprechung in der
.net-Bibliothek
z.B. List.map entspricht
Microsoft.FSharp.Collections.List.map
●
Zugriff auf Window, XDocument usw. ist erlaubt
→ Codebeispiel
Fazit
●
●
OCaml und F# sind sehr mächtige Sprachen
F# scheint für produktiven Einsatz recht gut
geeignet zu sein
●
Zugriff auf Systemschichten über .net
●
Verwendung von C# und VBA-Bibliotheken
●
XML-Verarbeitungsmöglichkeiten des .netFrameworks
Ende der Präsentation
für Fragen stehen wir zur Verfügung
Quellen
●
Syme, Don; Granicz, Cisterno, Antonio: Expert F#, 2007
●
Harrop, J. D.: OCaml for Scientists, 2005
●
Smith, Chris: Programming F#, 2010
●
Jason Hickey: Introduction to Objective Caml, 2008, www.cs.caltech.edu/courses/cs134/cs134b/book.pdf
●
Xavier Leroy: The Objective Caml system: Documentation and user’s manual 3.12, 2008, http://caml.inria.fr/pub/docs/manualocaml/index.html
●
MSDN F# Referenz, http://msdn.microsoft.com/en-us/library/dd233181.aspx
●
http://en.wikibooks.org/wiki/F_Sharp_Programming/Computation_Expressions
●
http://lookingsharp.wordpress.com/2010/02/27/fibonacci-fun-with-fsharp/
●
http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/
●
http://blog.matthewdoig.com/?p=98
●
http://www.heise.de/developer/artikel/F-funktionales-Pendant-zu-C-1140553.html
●
http://www.codingforfood.com/2010/09/f-infinite-sequences.html
●
http://enfranchisedmind.com/blog/posts/a-monad-tutorial-for-ocaml/
●
Caml Website, http://caml.inria.fr/
Herunterladen