Starten mit F#

Um zu starten und reinzuschnuppern braucht man nichts zu installieren. Entwicklungsumgebung also Code Editor und Compiler als Webseite gibt es gratis und ohne Anmeldung hier: Dieser läuft auf allen Systemen, auch für Apple iOS (iPad ohne Silverlight) Diese benötigen einen Web-Browser mit installiertem Microsoft Silverlight

Probiert aus, was euch am meisten zusagt. Unten sind zwei kurze Code Schnipsel zum Ausprobieren. Diese können einfach in die obigen Editoren kopiert werden um sie auszuführen.

Update: Gute Neuigkeiten, seit 12. Nov. 2014 ist von Microsoft das Visual Studio Community 2013 with Update 4 gratis hier erhältlich, die Installation oder das ISO Image hat einen Grösse von 6.9 GB. Mehr dazu  “Visual Studio Community 2013 – A Full-Featured IDE – FREE – Start coding the app of your dreams for Windows, Android, and iOS.” und “Opening up Visual Studio and .NET to Every Developer, Any Application”


Update: F# für Linux, Mac, Windows

Free Monodevelop wie hier beschrieben  http://www.monodevelop.com/download heisst dann (etwas verwirrend weil es umgetauft wurde) XamarinStudio.

Installation auf Windows 8.1 (Für andere F# Installationen empfiehlt sich http://fsharp.org/use/ )
Stand: 27.6.2015
Mit total ca. 100 MB download ist man dabei und die Installationszeit ist freundlich kurz, jedoch in 4 Schritten, aber alles ohne Windows zu booten.
1. .NET Framework 4.5:
    Download  http://go.microsoft.com/fwlink/p/?LinkId=397703
2. Install the free Visual F# Tools 3.1.2 from Microsoft
    Download (ca. 28 MB) http://www.microsoft.com/download/details.aspx?id=44011
3. GTK# for .NET 2.12.25:
    Download (ca. 25 MB) http://download.xamarin.com/GTKforWindows/Windows/gtk-sharp-2.12.25.msi
4. Xamarin Studio:
    Download (ca. 45 MB) http://download.xamarin.com/studio/Windows/XamarinStudio-5.9.2.4-0.msi

Im Xamarin Studio erstes F# Projekt erstellen (danach merkt er sich das)
Xamarin Studio F# Einstellungen
Selektierten F# Code im Editor ausführen mit Ctrl + Enter (nicht Alt + Enter wie in Visual Studio).


F# Beispiele

Auflistung .NET Assemblies

1: 
2: 
3: 
4: 
let methods =
    System.AppDomain.CurrentDomain.GetAssemblies()
    |> Seq.map (fun asm -> asm.GetTypes())
printfn "%A" methods
Die Ausgabe (gekürzt)
seq [[|System.Object; System.Runtime.Serialization.ISerializable; System.Runtime.InteropServices.Exception; System.Exception; System.Exception+_RestrictedErrorObject; System.ValueType; System.IComparable; System.IFormattable; System.IConvertible; …

Gray-Code Erzeugung

1: 
2: 
3: 
let (&) x = List.map((+)x)
let g x = ("0" & x) @ ("1" & (List.rev x))
printf "%A" ([""] |> g |> g |> g)
Gibt die 3-stelligen Gray-Codes aus. Für jedes |> g eine Stelle. Die Gray-Codes sind so angeordnet, dass immer nur ein Bit wechselt.
[“000″; “001”; “011”; “010”; “110”; “111”; “101”; “100”]
Tipp : Es ist klar das man als F# Neuling dies nicht gleich verstehen kann. Bitte nicht abschrecken lassen. Das Ergebnis soll etwas zum Staunen anregen. Es ist schon etwas kryptisch, aber es soll zeigen wie elegant und kompakt man Funktionen verknüpfen kann. Wenn man überhaupt nicht verstehen kann wie es funktionieren könnte, dann implementiere man den Gray-Code in seiner aktuell verwendeten Programmiersprache. Und pausiere das Lesen hier. STOP! nicht weiterlesen. Auflösung : Man wird erkennen, dass der Algorithmus auf Zeile 2 implementiert ist. D.h. es ist eher eine Spezifikation des Algorithmus, als eine imperative Abhandlung. Auf Zeile 1 wird ein Hilfsoperator & definiert der ein String mit einer String Liste verbindet. Der @ Operator verbindet zwei Listen. Und [ ] definiert eine Liste gefüllt mit einem leeren "" String. Der Pipe-Operator |> schiebt die Werte in die Funktion g, die der Generator für die nächste Stufe des Gray-Codes ist. Man könnte auch g(g(g([""]))) schreiben anstatt [""]|>g|>g|>g aber letzteres zeigt den Daten-Fluss viel intuitiver an. List.rev kehrt eine Liste um. Das printf macht die Ausagbe und mit "%A" als alles Formatierer.

F# Sprach Konstrukte

Wer schon eine Programmiersprache kennt, für den ist es sowieso einfach. Die vier wesentlichen Sprach Konstrukte sind
  • let : Zuweisung von Values und Funktionen
  • fun : Anonyme Funktion
  • type : Type Definition (Record, Class, Discriminated Union (DU))
  • match : Fallunterscheidung (das machtige “if” und “switch” in einem)
Zur Sprache F# selbst wird hier keine detaillierte Schritt für Schritt Abhandlung der kompletten Syntax gezeigt. Man findet die komplette F# Sprach Referenz “The F# Specification Language” als Nachschlagewerk gratis hier als PDF oder als Webseite .

Ausblick

Was macht F# so anderst?

Es sind die Kleinen, meist unterschätzten, Unterschiede und deren Konzepte in der Basis die, die Möglichkeiten in Höheren Ebenen wie Abstraktion und Komposition erst ermöglichen. Z.B. dass alle Values immutable sind, immer zugewiesen sind und es darum keine null (NULL) Referenzen vorkommen, dazu später mehr. Ich nenne sie Micro Patterns (Mikro Muster), es sind winzige Patterns mit wenig Code, die im Zusammenspiel, also der Komposition die wahre Funktion entfalten. Im Gegensatz zu den bekannten Objektorientierten Entwurfsmuster (Design Patterns), die aus mehreren zusammen agierenden Klassen bestehen, mit einigen Zeilen an Code, die sich pro Klasse über mehrere Files erstrecken können, so dass man, um den Zusammenhang zu erkennen, meist zu visuellen Darstellungen mittels UML Diagrammen greift.
Jetzt nehme ich etwas vorweg, der Clou an diesen Micro Patterns ist, dass diese das selbe wie die “riesigen” GoF Design Patterns, aber mit viel viel weniger Code (und ohne Klassen) bewerkstelligen können und somit überschaubar bleiben. Die Muster sind manchmal so klein, dass sie gleich als Sprachbestandteil von F# aufgehen.
Weiter geht’s dann im nächsten Blog.
val methods : seq<System.Type []>Full name: StartenvonF.methods
namespace System
type AppDomain = inherit MarshalByRefObject member ActivationContext : ActivationContext member AppendPrivatePath : path:string -> unit member ApplicationIdentity : ApplicationIdentity member ApplicationTrust : ApplicationTrust member ApplyPolicy : assemblyName:string -> string member BaseDirectory : string member ClearPrivatePath : unit -> unit member ClearShadowCopyPath : unit -> unit member CreateComInstanceFrom : assemblyName:string * typeName:string -> ObjectHandle + 1 overload member CreateInstance : assemblyName:string * typeName:string -> ObjectHandle + 3 overloads …Full name: System.AppDomain
property System.AppDomain.CurrentDomain: System.AppDomain
System.AppDomain.GetAssemblies() : System.Reflection.Assembly []
module Seqfrom Microsoft.FSharp.Collections
val map : mapping:(‘T -> ‘U) -> source:seq<‘T> -> seq<‘U>Full name: Microsoft.FSharp.Collections.Seq.map
val asm : System.Reflection.Assembly
System.Reflection.Assembly.GetTypes() : System.Type []
val printfn : format:Printf.TextWriterFormat<‘T> -> ‘TFull name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val x : string
Multiple items module Listfrom Microsoft.FSharp.Collections ——————– type List<‘T> = | ( [] ) | ( :: ) of Head: ‘T * Tail: ‘T list interface IEnumerable interface IEnumerable<‘T> member Head : ‘T member IsEmpty : bool member Item : index:int -> ‘T with get member Length : int member Tail : ‘T list static member Cons : head:’T * tail:’T list -> ‘T list static member Empty : ‘T list Full name: Microsoft.FSharp.Collections.List<_>
val map : mapping:(‘T -> ‘U) -> list:’T list -> ‘U listFull name: Microsoft.FSharp.Collections.List.map
val g : x:string list -> string listFull name: StartenvonF.g
val x : string list
val rev : list:’T list -> ‘T listFull name: Microsoft.FSharp.Collections.List.rev
val printf : format:Printf.TextWriterFormat<‘T> -> ‘TFull name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printf