28
Now Open: F# Brian McKenna Monday 24 th of January 2011

Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Now Open: F#Brian McKennaMonday 24th of January 2011

Page 2: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Why now?

● F# was first released around 2002● Original releases were under Microsoft

Research Shared Source license agreement● Not an open-source license

● November 2010: F# released under Apache license● Open-source!

Page 3: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Why F#?

● .NET platform● Portable and language independent

● Functional and object-oriented● OCaml, Scala, Fantom

● Largely OCaml compatible● Microsoft is taking F# concepts and putting them

into C# (the “mainstream”)● Provides great opportunities for parallelism● Whitespace sensitive (Python, Haskell)

Page 4: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

F# Interactive

● Read-evaluate-print loop (REPL)

Page 5: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Multi-paradigm

● Object-orientedtype Person (name) =

member this.Shower () =

printfn "%s is showering" name

member this.Eat s =

printfn "%s is eating %s" name s

let roger = Person "Roger"

roger.Shower ()

// Roger is showering

roger.Eat "lobster"

// Roger is eating lobster

● Functionallet rec quickSort = function

| [] -> []

| x :: xs ->

let lt =

List.filter ((>=) x) xs

let gt =

List.filter ((<) x) xs

quickSort lt @ [x] @

quickSort gt : List<int>

Page 6: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Type inference

let a = 10

// val a : int

let b = "test"

// val b : string

let f x = (x + 1).ToString()

// val f : int -> string

let g x = x

// val g : 'a -> 'a

// Explicit typing

let h (x : int) = x

// val h : int -> int

let i x : int = x

// val i : int -> int

Page 7: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

List comprehensions

[1..5] // [1; 2; 3; 4; 5]

[2..2..10] // [2; 4; 6; 8; 10]

[10..-2..2] // [10; 8; 6; 4; 2]

['a'..'f'] // ['a'; 'b'; 'c'; 'd'; 'e'; 'f']

[for x in 1..5 -> x * x] // [1; 4; 9; 16; 25]

[for x in 1..5 do if x <= 3 then yield x * x] // [1; 4; 9]

[for x in 1..3 do yield! [1..x]] // [1; 1; 2; 1; 2; 3]

[for x in 1..3 do for y in 1..2 -> x * y] // [1; 2; 2; 4; 3; 6]

Page 8: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Algebraic data types(product types)

// Tuples

(20, "Brian", "Brisbane")

// val it : int * string * string

// Records

type person = {

Age : int;

Name : string;

Location : string

}

{Age = 20; Name = "Brian"; Location = "Brisbane"}

// val it : person

Page 9: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Algebraic data types(sum type)

// Discriminated unions

type employee =

| PartTime of float * int // hourly rate by hours

| FullTime of int // salary

PartTime (18.5, 20)

// val it : employee

FullTime 70000

// val it : employee

Page 10: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Algebraic data types(enumerated type)

// Enum

type Size =

| Small = 1

| Medium = 2

| Large = 3

Size.Small

// val it : Size

Size.Large

// val it : Size

Page 11: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Pattern matching

let printItem = function

| Some x -> printfn "We have a %i." x

| None -> printfn "Nothing here!"

List.map printItem [Some 3; None; Some 1; Some 4; None]

// We have a 3.

// Nothing here!

// We have a 1.

// We have a 4.

// Nothing here!

Page 12: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

(+)

// val it : (int -> int -> int)

let addFive = (+) 5

// val addFive : (int -> int)

addFive 10

// val it : int = 15

Higher order functions(currying)

Page 13: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Higher order functions(lambdas and closures)

let createAdder x = fun y -> x + y

// val createAdder : int -> int -> int

let addThree = createAdder 3

// val addThree : (int -> int)

addThree 10

// val it : int = 13

Page 14: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Higher order functions(composition)

let absAddFour = (+) 4 << abs

// val absAddFour : (int -> int)

absAddFour -4

// val it : int = 8

let absAddFive = abs >> (+) 5

// val absAddFour : (int -> int)

absAddFive -4

// val it : int = 9

Page 15: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Explicit mutability(mutable variables)

// let a = 1

// let a = 2 // error FS0037: Duplicate definition of value 'a'

// a <- 2 // error FS0027: This value is not mutable

let mutable a = 1

let f x = do

a <- a + x

printfn "%A" a

f 1 // 2

f 10 // 12

Page 16: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Explicit mutability(mutable references)

let b = ref 100

let mutate x = do

let addValue r v = do

r := !r + v

printfn "%A" !r

addValue x 1

addValue x 10

mutate b

// 101

// 111

Page 17: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Units of measure

[<Measure>] type m

[<Measure>] type s

10.0<m>

// val it : float<m>

80.0<m> / 5.0<s>

// val it : float<m/s>

let addTwo = (+) 2.0<m>

// val addTwo : (float<m> -> float<m>)

addTwo 10.0<m>

// val it : float<m>

Page 18: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Lazy computations

open System

let rec fib = function

| 0 -> 0 | 1 -> 1 | n -> fib (n - 2) + fib (n - 1)

let timeLazy (l : Lazy<int>) =

let startTime = DateTime.Now

ignore (l.Force ())

let endTime = DateTime.Now

(endTime - startTime).TotalMilliseconds

let lazyFac = lazy fib 35

printfn "%A" (timeLazy lazyFac) // 521.507

printfn "%A" (timeLazy lazyFac) // 0.001

printfn "%A" (timeLazy lazyFac) // 0.001

Page 19: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Computation expressions(monads)

// Monad definition

type TraceBuilder () =

member x.Delay f =

printfn "Start tracing"

fun () -> f ()

member x.Bind (v, f) =

printfn "Binding %A" v

f v

member x.Return v =

printfn "Returning %A" v

fun () -> v

let trace = new TraceBuilder()

Page 20: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Computation expressions(monads)

// Workflow

let traceWorkflow = trace {

let! x = 3.0

return x + 0.14

}

let result = traceWorkflow ()

printfn "%A" (result ())

// Start tracing

// Binding 3.0

// Returning 3.14

// 3.14

Page 21: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Async workflows

let rec fib = function

| 0 -> 0 | 1 -> 1 | n -> fib (n - 2) + fib (n - 1)

let asyncFib n = async { printfn "%A" (fib n) }

Async.Parallel [| for i in 25..30 -> asyncFib i |]

|> Async.RunSynchronously

// 832040

// 514229

// 75025

// 196418

// 121393

// 317811

Page 22: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Code quotations

open Microsoft.FSharp.Quotations.Patterns

open Microsoft.FSharp.Quotations.DerivedPatterns

let concatMap f = List.map f >> String.concat " "

let rec toPrefix = function

| Value (obj, _) -> obj.ToString()

| SpecificCall <@ ( + ) @> (_, _, exprs) ->

"(+ " + concatMap toPrefix exprs + ")"

| SpecificCall <@ ( * ) @> (_, _, exprs) ->

"(* " + concatMap toPrefix exprs + ")"

| _ -> ""

printfn "%s" (toPrefix <@ 1 + 2 * 3 @>) // (+ 1 (* 2 3))

Page 23: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Extensions

// Module extension

module String =

let upper (s : string) = s.ToUpper ()

let concatMap sep f = List.map f >> String.concat sep

String.concatMap "! " String.upper ["Oh"; "my"; "god"; "a cat"]

// OH! MY! GOD! A CAT

// Type extension

type System.String with

member this.FirstChar =

this.[0]

"Test".FirstChar // T

Page 24: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

MonoDevelop

● Awesome plugin

Page 25: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Compiling your own F#

● Currently requires a recent version of Mono● Later than revision a5725456

$ git clone https://github.com/mono/mono.git

$ cd mono

$ ./autogen.sh && make && make install

$ git clone https://github.com/fsharp/fsharp.git

$ cd fsharp

$ autoreconf && ./configure && make && make install

Page 26: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Obstacles

● Officially released in code-drop fashion● Can't see the Microsoft F# Team changes● Not accepting patches● Have to merge in community changes

● Slightly buggy on Mono● More so with Microsoft version

Page 27: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

You can help

● Help with community F# tools● https://github.com/fsharp● Fork, fix and submit pull request

● fsharp-opensource mailing list● http://groups.google.com/group/fsharp-opensource

● Let the official F# team know about bugs● [email protected]

Page 28: Now Open: F# · Why F#? .NET platform Portable and language independent Functional and object-oriented OCaml, Scala, Fantom Largely OCaml compatible Microsoft is taking F# concepts

Thanks!

● Blog● http://brianmckenna.org/

● Twitter● http://twitter.com/puffnfresh

● F# fork● http://github.com/pufuwozu/fsharp