Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
Now Open: F#Brian McKennaMonday 24th of January 2011
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!
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)
F# Interactive
● Read-evaluate-print loop (REPL)
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>
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
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]
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
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
Algebraic data types(enumerated type)
// Enum
type Size =
| Small = 1
| Medium = 2
| Large = 3
Size.Small
// val it : Size
Size.Large
// val it : Size
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!
(+)
// val it : (int -> int -> int)
let addFive = (+) 5
// val addFive : (int -> int)
addFive 10
// val it : int = 15
Higher order functions(currying)
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
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
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
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
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>
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
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()
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
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
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))
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
MonoDevelop
● Awesome plugin
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
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
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]
Thanks!
● Blog● http://brianmckenna.org/
● Twitter● http://twitter.com/puffnfresh
● F# fork● http://github.com/pufuwozu/fsharp