Busy Developer's Guide to F#

ted@tedneward.com | Blog: http://blogs.tedneward.com | Twitter: tedneward | Github: tedneward | LinkedIn: tedneward

Objectives

Get started with F#

Functional Programming

What's it mean, exactly?

Concepts

What's wrong with imperative statements?

Concepts

Functional languages

Concepts

Some basic functional concepts

Some optional functional concepts

F# Overview

From a high level, what is this thing called 'F#'?

Overview

What is F#?

Overview

General-purpose

Overview

Object-oriented

Overview

Functional

Overview

Hybrid

Overview

.NET Platform

Overview

Visual Studio Integration

Overview

Some example F# code

let message = "Hello, world! (From F#)"
System.Console.WriteLine(message)

for i = 1 to 10 do
    System.Console.WriteLine(message + " " + i.ToString())

Overview

Elements of note

Overview

Three modes of execution

Basics

Because we all have to start somewhere

Basics

Syntax

Basics

let

Basics

let

  let x = 5
  let y = 4.7
  let message = "Now is the time for all good men"
  let multilineMessage = "Now is the time
  for all good men
  to take up the cause
  of their country."

Basics

Types

Bounded Types

Basics

() : unit

Basics

Arithmetic operators

Boolean operators

Basics

Comparison operators

Basics

Functions

Basics

More let

  let add l r = l + r
  
  let leetSpeak (phrase : string) =
    phrase.
      Replace('e', '3').
      Replace('o', '0')
  let leet = leetSpeak "leet" // l33t
  
  let tedTest test = test "Ted"
  let isMe me =
    if me = "Ted" then
      "It is Ted!"
    else
      "Dunno who you are"
  
  tedTest isMe

Basics

Control flow

Basics

More let

  let isOdd n =
    if (n / 2) = (n % 2) then
      true
    else
      false
  
  for i = 1 to 10 do
    System.Console.WriteLine(i)
  
  let evens n =
    [
      for i in 0..n do
        if i % 2 = 0 then
          yield i
    ]
  let evenSingles = evens 9 // 0, 2, 4, 6, 8

Basics

Pattern matching

Basics

Pattern matching

<</Users/tedneward/Projects/Presentations.git/Content/FSharp/basics.fs NOT FOUND>>

Basics

Lists

Basics

Lists

  let list1 = [ ] // empty list
  let list2 = [1; 2; 3] // list of 1, 2, 3
  let list3 = 0 :: list2 // list of 0, 1, 2, 3
  let range = [1 .. 100] // list of 1, 2, ..., 99, 100
  
  // Common to use for comprehensions to build a list
  let evens n =
    [ for i in 0 .. n do
        if i % 2 = 0 then
          yield i ]
  let evenSingles = evens 9 // 0, 2, 4, 6, 8
  
  // Lists have a number of functions; more on this later

Basics

Lists

  let rec factorial n =
    if n = 0 then 1 else n * factorial (n-1)
  
  let rec sumList xs =
    match xs with
    | []    -> 0
    | y::ys -> y + sumList ys

Basics

Sequences

Basics

Lists

  let allPositiveIntegers =
    seq { for i in 1 .. System.Int32.MaxValue do
            yield i }   // fits in memory
            
  let alphabet = seq { for c in 'A' .. 'Z' -> c }
  let abc = Seq.take 3 alphabet  // seq ['A';'B';'C']
  
  // Prove it!
  let noisyAlphabet =
    seq {
      for c in 'A' .. 'Z' do
        printfn "Yielding %c" c
        yield c
    }
  let fifthLetter = Seq.nth 4 noisyAlphabet   // 'E'

Basics

Tuples

Basics

Tuples

  let speaker = ("Ted", "Neward", "iTrellis")
    // speaker is string * string * string
  let city = ("Seattle", "Washington", 5000000)
    // city is string * string * int
  let person = ("Charlotte", "Neward", 39)
    // person is string * string * int
  
  let firstName, lastName, age = person
    // firstName = "Charlotte"
    // lastName = "Neward"
    // age = 39
  
  let add l r = l + r
    // add is int -> int -> int
  let Add (l : int, r : int) = l + r
    // Add is (int * int) -> int

Basics

Tuples

  let people =
    [ ("Charlotte", "Neward", 39); ("Ted", "Neward", 42);
      ("Fred", "Flintstone", 51); ("Katy", "Perry", 21) ]
  
  let personsAge p ln =
    match p with
    | (_, ln, age) -> age
  
  let ages = [ for p in people do
                  yield personsAge p "Neward" ]

Basics

Option

Basics

Discriminated Unions

Basics

Discriminated Unions

  type Suit =
    | Heart
    | Diamond
    | Spade
    | Club
  type PlayingCard =
    | Ace of Suit    | King of Suit
    | Queen of Suit  | Jack of Suit
    | PointCard of int * Suit
  let deckOfCards =
    [
      for suit in [Spade; Club; Heart; Diamond] do
        yield Ace(suit)
        yield King(suit)
        yield Queen(suit)
        yield Jack(suit)
        for value in 2 .. 10 do
          yield PointCard(value, suit)
    ]

Basics

Discriminated Unions and Pattern matching

  let describeCards cards =
    match cards with
    | cards when List.length cards > 2 -> failwith "Too few cards"
    | [Ace(_); Ace(_)] -> "Pocket Rockets"
    | [King(_); King(_)] -> "Cowboys"
    | [PointCard(2, _); PointCard(2, _)] -> "Ducks"
    | [PointCard(x, _); PointCard(y, _)] when x = y -> "Pair
    | [first; second] -> "You got nuttin"

Basics

Modules

Namespaces

Both are "open"ed to use

Objects

Because it's object-oriented, too

Objects

Records

Objects

Records

open System

type PersonRecord =
  { FirstName : string; LastName: string; Age : int}
  member this.FullName =
      FirstName + " " + LastName
  member this.Greet(other : string) =
      String.Format("{0} greets {1}", this.FirstName, other)

let ted = { FirstName = "Ted"; LastName = "Neward"; Age = 42 }
Console.WriteLine("{0} {1} is {2}", ted.FirstName, ted.LastName, ted.Age)

// Cloning records: use 'with'
let michael = { ted with FirstName="Michael"; Age=20 }

Objects

Classes

Objects

Classes: constructors, fields

type Person(firstName : string, lastName : string, age : int) =
    member p.FirstName = firstName
    member p.LastName = lastName
    member p.Age = age

Objects

Classes

Objects

Classes: methods

    // from before ...
    member p.Work() =
        System.Console.WriteLine(firstName + " is hard at work.")
    member p.Play(activity) =
        System.Console.WriteLine(firstName + " loves " + activity)

Objects

Classes

Objects

Classes: methods

    member p.Drink(?kind : string, ?amount : int) =
        let bK = match kind with None -> "IPA" | Some b -> b
        let bA = match amount with None -> 1 | Some amt -> amt
        System.Console.WriteLine("I'm drinking {0} {1}s!", bA, bK)
    
let p = Person("Ted", "Neward", 42)
p.Drink("Macallan", 1)
p.Drink(amount=2, kind="Zinfandel")

Objects

Inheritance (implementation)

Objects

Classes: inheritance

type Student(fN:string, lN:string, a:int, subject:string) =
    inherit Person(fN, lN, a)
    member st.Subject = subject
    override st.ToString() =
        System.String.Format("[Student: subject = {0}, " +
            base.ToString() + "]", subject)
          
let s = Student("Michael", "Neward", 20, "Video Game Design")
s.Drink()

Objects

Inheritance (interfaces)

Objects

Classes: interfaces

type IStudy =
    abstract Study : string -> unit
    
type IAlsoStudy =
    interface
        abstract member Study : string -> unit
    end
    
type Programmer(fN:string,lN:string,a:int) =
    inherit Person(fN,lN,a)
    interface IStudy with
        member this.Study (subject:string) : unit =
            printfn "Now I know %s !" subject
    
let db = Programmer("Don", "Box", 54)
let dbs = db :> IStudy
dbs.Study("Kung Fu")

Objects

Object Expressions

Objects

Classes: object expressions

let monkey =
  { new IStudy with
      member m.Study(subject:string) =
          System.Console.WriteLine("Ook eek aah aah {0}", subject) }
monkey.Study("Visual Basic")

Summary

There's a lot of power buried inside this beast

Resources

Books

Resources

Web

Credentials

Who is this guy?