SlideShare a Scribd company logo
1 of 38
Download to read offline
F# AND REACTIVE
PROGRAMMING FOR IOS
Presented at Indy CocoaHeads, May 2014	

Brad Pillow, PillowSoft LLC	

www.pillowsoft.com	

https://github.com/pillowsoft	

twitter: @BradPillow
OVERVIEW
• What’s new in Xamarin for F# and iOS	

• What is F#	

• What is RX (Reactive Extensions) 	

• Using both on iOS
It’s going to be a very high-level overview….
WHAT'S NEW IN XAMARIN
• Support for latest iOS	

• IDE improvements	

• Speed/memory footprint optimizations	

• Generics and JIT issues largely fixed	

• More PCL (portable class library) support	

• Soon to have “shared project” support	

• Component for portable RX support	

• Most importantly to me, F# support
POSSIBLE TARGETS
• iOS: iPhone, iPad	

• Mac Desktop	

• Android:Android phones,Android tablets, Google Glasses,Amazon
FireTV,Android Watches
With Xamarin:
With Visual Studio:
• Windows Store & Desktop	

• Windows Phones
With FunScript or WebSharper:
• Web & Web Apps
MY FIRST FUNCTIONAL
LANGUAGE
• Back in 1976 started using APL -The
Array Programming Language,
developed by IBM in the 60’s (over 1/2
a century ago!)	

• Now experiencing a minor resurgence
(see J Language)	

• I like to call it “programming in the
language of the ancients” for Stargate
Fans	

• Example, find all prime numbers from 1
to R: 	

• (~R∊R∘.×R)/R←1↓ιR
WHY DOTHEY CALL IT
FUNCTIONAL?
The name functional comes from mathematics. If we think about
pure math functions like:	

f(x) = sin(x)
we know that for any value of x, we will always get the same
value for f(x) when we do the computation.This allows us to
reason better about our function, avoid the complications of
mutation and state, and do optimizations like memoization.
F# AND RX	

LEARNING CURVE
• First time I tried F# I just
didn’t get it	

• I tried writing OOP style	

• That’s does not work!	

• Same with RX	

• Go with the grain and you’ll
have some wonderful aha
moments
THE BASICS
• Type Inference	

• ImmutableValues vsVariables	

• Recursion or Loops?	

• Function Composition Rather than Inheritance	

• Functions as First-OrderTypes	

• Pattern Matching	

• But what about OOP?Yep, backward compatibility…
F# is essentially a .Net implementation of OCaml, combining the
power and expressive syntax of functional programming with the tens
of thousands of classes which make up the .NET class library
THE BASICS A
Type Inference
!
Let the compiler worry about your types and proof checking that
your code is correct. Known as Hindley-Milner type inference.The
compiler is essentially deriving types by ensuring that everything
makes sense.All the goodness of less keystrokes with dynamic typing,
with all the power of static typing.
Immutable Values versus variables
!
Being a functional programming language, F# encourages use of values
or immutable variables.You can use mutable variables, but it’s typically a
“code smell”.While it may seem inefficient to ignore mutation,
researchers have come up with impressive immutable data structures
that are fast and share memory.
RECURSION OR LOOPS
• F# and most functional programming languages prefer recursion over
looping, as looping implies mutability	

• If we recurse, then we are typically passing values up and down through
our recursion…values mean immutability	

• Fib in recursive form: let rec fib n =
if n <= 2 then 1
else fib (n - 1) + fib (n - 2)
• Recursive functions can sometimes be hard to understand	

• You will typical use fold, unfold and other functional variants to replace recursing
let data = [("Cats",4);
("Dogs",5);
("Mice",3);
("Elephants",2)]
let count = List.fold (fun acc (nm,x) -> acc+x) 0 data
printfn "Total number of animals: %d" count
Function Composition Rather than Inheritance
// create an "adder" by partial application of add
let add42 = (+) 42 // partial application
add42 1
add42 3
!
// create a new list by applying the add42 function to each element
[1;2;3] |> List.map add42
!
// create a "tester" by partial application of "less than"
let twoIsLessThan = (<) 2 // partial application
twoIsLessThan 1
twoIsLessThan 3
!
// filter each element with the twoIsLessThan function
[1;2;3] |> List.filter twoIsLessThan
!
// create a "printer" by partial application of printfn
let printer = printfn "printing param=%i"
!
// loop over each element and call the printer function
[1;2;3] |> List.iter printer
Functions as First-OrderTypes
F# liberally uses functions as types and it is a basic component of using a powerful technique called higher order
functions.A higher-order function is a function that takes another function as a parameter, or a function that
returns another function as a value, or a function which does both.	

!
The Composition Function (<< operator)	

In algebra, the composition function is defined as compose(f, g, x) = f(g(x)), denoted f o g.	

!
let f x = x*x
let g x = -x/2.0 + 5.0
let fog = f << g
Console.WriteLine(fog 0.0) // 25
Console.WriteLine(fog 1.0) // 20.25
!
The Pipeline Function ( |> operator)	

The pipeline operator, |> , is one of the most important operators in F#. Here is how it is defined:	

let inline (|>) x f = f x
!
It allows us to write:	

[1 ;2; 3; 4; ] |> List.filter (fun e -> e % 2 = 0) |> List.map (fun v -> v * v)
rather than:	

List.map (fun v -> v * v) (List.filter (fun e -> e % 2 = 0) [1 ;2; 3; 4; ])
The “pipeline” notation is much easier to read and conveys meaning better.
QUICK INTROTO F#	

VARIABLES…SORT OF
// single line comments use a double slash	

(* multi line comments use (* . . . *) pair	

!
-end of multi line comment- *)	

!
//The "let" keyword defines an (immutable) value - note that no types are needed	

let myInt = 5
let myFloat = 3.14
let myString = "hello" 	

let myList = [ “dog”; “cat”; “cow”;]
let myArray = [| 1; 2; 3; 4; ]
let mySequence = seq { 1..1000 } // lazy sequences
Credits: http://fsharpforfunandprofit.com/posts/fsharp-in-60-seconds/
QUICK INTROTO F#	

LISTS
let twoToFive = [2;3;4;5] 	

 // Square brackets create a list with	

	

	

 	

 	

 // semicolon delimiters.	

let oneToFive = 1 :: twoToFive 	

 // :: creates list with new 1st element	

!
// The result is [1;2;3;4;5]	

!
let zeroToFive = [0;1] @ twoToFive // @ concats two lists	

!
!
// NOTE: commas are never used as delimiters, only semicolons	

!
QUICK INTROTO F#	

FUNCTIONS
//The "let" keyword also defines a named function.	

let square x = x * x 	

 // Note that no parens are used.	

square 3 	

	

 // Now run the function.Again, no parens.	

!
let add x y = x + y 	

 // don't use add (x,y)! It means something	

	

 	

 // completely different.	

add 2 3 	

 	

 // Now run the function.	

!
// to define a multiline function, just use indents. No semicolons needed.	

let evens list =
let isEven x = x%2 = 0 	

// Define "isEven" as a sub function	

List.filter isEven list 	

 // List.filter is a library function	

	

 	

 // with two parameters: a boolean function	

	

 	

 // and a list to work on	

!
evens oneToFive 	

 // Now run the function
QUICK INTROTO F#	

MORE FUNCTIONS
//You can use parens to clarify precedence. In this example,	

// do "map" first, with two args, then do "sum" on the result.	

// Without the parens, "List.map" would be passed as an arg to List.sum	

let sumOfSquaresTo100 =
List.sum ( List.map square [1..100] )
!
//You can pipe the output of one operation to the next using "|>"	

// Here is the same sumOfSquares function written using pipes	

let sumOfSquaresTo100piped =
[1..100] |> List.map square |> List.sum 	

 	

 // "square" was defined earlier	

!
// you can define lambdas (anonymous functions) using the "fun" keyword	

let sumOfSquaresTo100withFun =
[1..100] |> List.map (fun x->x*x) |> List.sum
!
// In F# there is no "return" keyword.A function always	

// returns the value of the last expression used.
QUICK INTROTO F#	

PATTERN MATCHING
// Match..with.. is a supercharged case/switch statement.	

let simplePatternMatch =
let x = "a"
match x with
| "a" -> printfn "x is a"
| "b" -> printfn "x is b"
| _ -> printfn "x is something else" // underscore matches anything
!
// Some(..) and None are roughly analogous to Nullable wrappers	

let validValue = Some(99)
let invalidValue = None
!
// In this example, match..with matches the "Some" and the "None",	

// and also unpacks the value in the "Some" at the same time.	

let optionPatternMatch input =
match input with
| Some i -> printfn "input is an int=%d" i
| None -> printfn "input is missing"
!
optionPatternMatch validValue
optionPatternMatch invalidValue
QUICK INTROTO F#	

DATATYPES
//tuples are quick 'n easy anonymous types	

let twoTuple = 1, 2
let threeTuple = “a", 2, true
!
//record types have named fields	

type Person = {First:string; Last:string}
let person1 = {First="john"; Last="Doe"}
!
//union types have choices	

type Temp =
| DegreesC of float
| DegreesF of float
let temp = DegreesF 98.6
!
//types can be combined recursively in complex ways	

type Employee =
| Worker of Person
| Manager of Employee list
let jdoe = { First=“John"; Last=“Doe" }
let worker = Worker jdoe
QUICK INTROTO F#	

PRINTING
//The printf/printfn functions are similar to the	

// Console.Write/WriteLine functions in C#….but strongly typed!	

printfn "Printing an int %i, a float %f, a bool %b" 1 2.0 true
printfn "A string %s, and something generic %A" "hello" [1;2;3;4]
!
// all complex types have pretty printing built in	

printfn "twoTuple=%A,nPerson=%A,nTemp=%A,nEmployee=%A"
twoTuple person1 temp worker
!
//There are also sprintf/sprintfn functions for formatting data	

// into a string, similar to String.Format.
QUICK INTROTO F#	

THE REPL
Definition of REPL: Read-Eval-Print Loop	

!
The REPL is your friend. Use it heavily while learning F#. 	

Excellent to use when working out small algorithms as well
QUICK INTROTO F#	

THE REPL
Peter Norvig's Spelling Corrector in F#	

http://norvig.com/spell-correct.html
open System.IO
open System.Text.RegularExpressions
!
let edits1 (word : string) =
let splits = [for i in 0 .. word.Length do yield (word.[0..i-1], word.[i..])]
let deletes = [for a, b in splits do if b <> "" then yield a + b.[1..]]
let transposes = [for a, b in splits do if b.Length > 1 then yield a + string b.[1] + string b.[0] + b.[2..]]
let replaces = [for a, b in splits do for c in 'a'..'z' do if b <> "" then yield a + string c + b.[1..]]
let inserts = [for a, b in splits do for c in 'a'..'z' do yield a + string c + b]
deletes @ transposes @ replaces @ inserts |> Set.ofList
!
let NWORDS =
File.ReadAllText "big.txt" |> (Regex "[a-zA-Z]+").Matches |> Seq.cast |> Seq.map (fun (m:Match) -> m.Value.ToLower()) |> Seq.countBy id |> Map.ofSeq
!
let known_edits2 word = [for e1 in edits1(word) do for e2 in edits1(e1) do if Map.containsKey e2 NWORDS then yield e2] |> Set.st
let known words = [for w in words do if Map.containsKey w NWORDS then yield w] |> Set.ofList
!
let (<||>) (first : Lazy<_>) (second : Lazy<_>) : Lazy<_> = lazy(if Set.isEmpty first.Value then second.Value else first.Value)
let correct word =
(lazy known([word]) <||> lazy known(edits1(word)) <||> lazy known_edits2(word) <||> lazy Set.singleton word).Value
|> Seq.sortBy (fun w -> -NWORDS.[w]) |> Seq.head
!
// Example
correct "speling"
WHY RX
Integrated
LINQ (language Integrated Query) is integrated into the C# language.	

Unitive
Using LINQ allows you to leverage your existing skills for querying data at rest (LINQ to SQL, LINQ to XML or LINQ to objects) to
query data in motion.You could think of Rx as LINQ to events. LINQ allows you to transition from other paradigms into a common
paradigm. For example you can transition a standard .NET event, an asynchronous method call, aTask or perhaps a 3rd party
middleware API into a single common Rx paradigm. By leveraging our existing language of choice and using familiar operators like
Select,Where, GroupBy etc, developers can rationalize and communicate designs or code in a common form.	

Extensible
You can extend Rx with your own custom query operators (extension methods).	

Declarative
LINQ allows your code to read as a declaration of what your code does and leaves the how to the implementation of the
operators.
WHENTO USE RX?
Managing events like these is what Rx was built for:	

• UI events like mouse move, button click	

• Gestures - see 	

• Domain events like property changed, collection
updated, "Order Filled", "Registration accepted" etc.	

• Infrastructure events like from file watcher, system
events	

• Integration events like a broadcast from a message
bus or a push event
KEY RX DATATYPES
• IObserver<T> - an object that can observe an
observable by subscribing to it, receives OnNext,
OnError and OnCompleted form observables	

• IObserverable<T> - an object that can be observed.
Allows other to observe it via the Subscribe method.	

• ISubject<T> - and observer and an observable
F# RX OPERATORS
add - Create an observer which permanently subscribes to the given observable and which calls
the given function for each observation.	

!
subscribe - Create an observer which subscribes to the given observable and which calls the
given function for each observation.	

!
map - Return an observable which transforms the observations of the source by the given
function.	

!
filter - Return an observable which filters the observations of the source by the given function.	

!
scan - Return an observables which, for each observer, allocates an item of state and applies the
given accumulating function to successive values arising from the input.The returned object will
trigger observations for each computed state value, excluding the initial value.The returned
object propagates all errors arising from the source and completes when the source completes.	

!
choose - Return an observable which chooses a projection of observations from the source
using the given function.	

!
split - Return two observables which split the observations of the source by the given function.
RX EXAMPLE A
let observable = new Subject<int>()	

!
let mySubscribe =	

let interested = observable |> Observable.filter (fun x -> x%2=0)	

interested.Subscribe(fun i -> Console.WriteLine("Hello " + i.ToString()))	

!
let myYields =	

observable.OnNext(1)	

observable.OnNext(2)	

observable.OnNext(3)	

observable.OnNext(4)
RX EXAMPLE B
// Create form	

let form = new Form(Visible=true,TopMost=true,Text="Event Sample")	

!
// Create under and over for X andY coordinates	

let (overEvent, underEvent) = form.MouseDown	

|> Observable.merge form.MouseMove	

|> Observable.filter (fun args -> args.Button = MouseButtons.Left)	

|> Observable.map (fun args -> (args.X, args.Y))	

|> Observable.partition (fun (x, y) -> x > 100 && y > 100)	

!
// Subscribe to each	

let overSubscription = overEvent |> Observable.subscribe (fun (x, y) -> printfn "Over (%d, %d)" x y)	

let underSubscription = underEvent |> Observable.subscribe (fun (x, y) -> printfn "Under (%d, %d)" x y)	

	

// Much later, clean up	

overSubscription.Dispose()	

underSubscription.Dispose()
SO MUCH MORE!!
• Quotations - your code as meta-data	

• Computation Expressions - for language oriented
programming	

• Type Providers - type safe access to untyped data	

• Async - came before C#’s but just as powerful	

• Agents - for multi-threaded and concurrent apps 	

• Active Patterns - wrap ad hoc values and objects in
union-like structures for use in pattern matching.	

• Units Of Measurement - “unit safe” computing	

• DSL’s - define more user friendly, internal dsl’s
F#TYPE PROVIDERS	

TWITTER SEARCH IN 10 LINES
typeT = FSharp.Data.JsonProvider<"http://search.twitter.com/search.json?q=%23fsharp&lang=en&rpp=1&page=1">	

let tweets (tag : string) (since : System.DateTime) =	

let enc = System.Web.HttpUtility.UrlEncode : string -> string	

let rec page n = 	

let data =T.Load(sprintf "http://search.twitter.com/search.json?q=%s&rpp=100&page=%d&since=%4d-%02d-%02d" (enc tag) n since.Year
since.Month since.Day)	

seq{	

yield! data.Results	

if not (Seq.isEmpty data.Results) then yield! page (n + 1)	

}	

page 1	

!
// usage	

tweets "#fsharp" (System.DateTime.Parse("5/17/2013"))	

|> Seq.iter ( fun t -> printfn "%-21O %-15s %s" t.CreatedAt t.FromUser t.Text )
Ref: http://fssnip.net/iu
SIMPLE IOS EXAMPLE
namespace Simple
open System
open MonoTouch.UIKit
open MonoTouch.Foundation
open System.Drawing
type ContentView ( color : UIColor ) as self =
inherit UIView ()
do
self.BackgroundColor < - color
type SimpleController ( ) =
inherit UIViewController ()
override this.ViewDidLoad () =
this.View <- new ContentView(UIColor.Blue)
[<Register ("AppDelegate")>]
type AppDelegate () =
inherit UIApplicationDelegate ()
let window = new UIWindow (UIScreen.MainScreen.Bounds)
// This method is invoked when the application is ready to run.
override this.FinishedLaunching (app, options) =
let viewController = new SimpleController()
viewController.Title <- "F# Rocks"
let navController = new UINavigationController(viewController)
window.RootViewController <- navController
window.MakeKeyAndVisible ()
true
module Main =
[<EntryPoint>]
let main args =
UIApplication.Main (args, null, "AppDelegate")
0
Credits: http://www.knowing.net/index.php/2013/11/13/f-ios-program-39-lines-of-code/
IOS EXAMPLE WITH RX
member this.Setup() =
let WIDTH = 32.0f
!
let chars =
" F# reacts to events!"
|> Seq.map (fun c ->
new UILabel(
Text = c.ToString(System.Globalization.CultureInfo.InvariantCulture),
Frame = RectangleF(100.f, 100.f, 24.f, 24.f),
BackgroundColor = UIColor.Clear,
TextAlignment = UITextAlignment.Center,
TextColor = UIColor.White,
Font = UIFont.FromName("courier", 24.0f) ))
|> Seq.toArray
!
!
do
for tb in chars do
this.AddSubview(tb)
!
this.AddSubview(
new UILabel(
Text = "Hello World!",
Frame = RectangleF(50.f, 50.f, 400.f, 50.f),
BackgroundColor = UIColor.Clear,
TextAlignment = UITextAlignment.Left,
TextColor = UIColor.White,
Font = UIFont.FromName("courier", 32.0f) ));
!
this.BackgroundColor <- color
this.UserInteractionEnabled <- true
this.MultipleTouchEnabled <- true
!
touchMoveEvent
|> Observable.add (fun p ->
async {
for i in 0..chars.Length-1 do
do! Async.Sleep(90)
this.UpdateLabelPosition(chars.[i], p, i)
} |> Async.StartImmediate
)
|> ignore
VIEWMODEL FORTIPCALC UI
type MainViewModel() =
let payCommand = new ReactiveCommand()
let _ = payCommand.Subscribe(fun (boolVal) -> printfn "Paid")
!
let subTotalText = new ReactiveProperty<string>()
let subTotal = new ReactiveProperty<float>()
let tipPercent = new ReactiveProperty<float>()
let calculatedTip = dependentsToReactiveProperty<float, float, float> subTotal tipPercent (fun x y -> x * (y / 100.0))
let calculatedTotal = dependentsToReactiveProperty<float, float, float> subTotal calculatedTip (fun x y -> x + y)
!
member this.Subtotal with get() = subTotal
member this.TipPercent with get() = tipPercent
member this.CalculatedTip with get() = calculatedTip
member this.CalculatedTotal with get() = calculatedTotal
member this.PayCommand with get() = payCommand
!
member this.InputText with get () = inputText
member this.DisplayText with get() = displayText
member this.ReplaceTextCommand with get() = replaceTextCommand
DSL FORVIEW A
this.mainModel <- new MainViewModel()
!
let payButton = Button (text = "Click Me!")
let subtotalLabel = Label (text = "Subtotal:")
let subtotalTextField = TextField ()
let tipPercentLabel = Label (text = "Tip Percent:")
let tipPercentTextField = TextField ()
let tipPercentSlider = Slider(min = 0., max = 100.)
let totalLabel = Label (text = "Total:")
let totalValueTextField = TextField ()
!
let tipView = View(content = [
subtotalLabel; subtotalTextField;
tipPercentSlider; tipPercentLabel; tipPercentTextField;
totalLabel; totalValueTextField;
payButton;
loadTemplateButton;
loadMarkdownButton;
webView;
])
!
let _ = this.mainModel.TipPercent.Subscribe(fun f -> printfn "slider moved to %f" f)
let _ = this.mainModel.Subtotal.Subscribe(fun f -> printfn “sub-total is %f" f)
!
let altUIBindings = [
Command(payButton, this.mainModel.PayCommand );
Command(loadTemplateButton, loadTemplateCommand );
Command(loadMarkdownButton, loadMarkdownCommand );
ValueToFromFloat(tipPercentSlider, this.mainModel.TipPercent);
ValueToFromString(tipPercentTextField, this.mainModel.TipPercent |> floatToStringProperty);
ValueToString(subtotalTextField, this.mainModel.Subtotal |> floatToStringProperty)
ValueFromString(totalValueTextField, this.mainModel.CalculatedTotal |> floatToStringProperty)
]
DSL FORVIEW B
let layoutConstraints = [
UIConstraint( sprintf "|-[%s]-[%s]-[%s]-|" tipPercentSlider.Id tipPercentLabel.Id tipPercentTextField.Id, [LayoutAlignOption.AlignAllBaseline]);
UIConstraint( sprintf "[%s]-[%s]-|" totalLabel.Id totalValueTextField.Id, [LayoutAlignOption.AlignAllBaseline]);
UIConstraint( sprintf "[%s]-[%s]-|" subtotalLabel.Id subtotalTextField.Id, [LayoutAlignOption.AlignAllBaseline]);
UIConstraint( sprintf "V:|-[%s]" subtotalLabel.Id);
UIConstraint( sprintf "V:[%s]-[%s]" subtotalLabel.Id tipPercentLabel.Id);
UIConstraint( sprintf "V:[%s]-[%s]" tipPercentLabel.Id totalLabel.Id);
UIConstraint( sprintf "V:[%s]-[%s]-[%s]" subtotalLabel.Id tipPercentLabel.Id totalLabel.Id, [LayoutAlignOption.AlignAllRight]);
UIConstraint( sprintf "[%s(>=70)]" tipPercentTextField.Id);
UIConstraint( sprintf "V:[%s(>=20)]" tipPercentTextField.Id);
UIConstraint( sprintf "V:[%s(==%s)]" subtotalTextField.Id tipPercentTextField.Id);
UIConstraint( sprintf "V:[%s(==%s)]" totalValueTextField.Id tipPercentTextField.Id);
UIConstraint( sprintf "[%s(==%s)]" tipPercentSlider.Id tipPercentTextField.Id);
UIConstraint( sprintf "V:[%s]-[%s]" totalLabel.Id payButton.Id);
!
UIConstraint( sprintf "V:[%s]-|" webView.Id);
UIConstraint( sprintf "|-[%s]-|" webView.Id);
UIConstraint( sprintf "V:[%s]-[%s]-[%s]-[%s]" payButton.Id loadTemplateButton.Id loadMarkdownButton.Id webView.Id,
[LayoutAlignOption.AlignAllCenterX]);
UIConstraint(payButton).WithSameCenterX(tipView);
]
let viewSpec = { content = tipView; layout = layoutConstraints; bindings = altUIBindings }
let viewFactory = UIFactory(viewSpec)
let mainView = viewFactory.Build()
!
this.ContentView <- mainView
()
WHYYOU SHOULD
INVESTIGATE F# & RX
• You like Python and wish it was a statically typed language	

• You like functional languages like Lisp, but have gone insane
looking at too many parenthesis	

• You like Objective-C, C# or C++, but feel there just has to be
a better way to express your ideas	

• You like math and see to elegance and beauty in function
composition, immutability, folds, monoids, etc.	

• You want to use one language and yet target an amazing
variety of devices and platforms with native performing code
WARNING!!!
It’s addictive! Don’t believe me? Follow #FSharp onTwitter.
THANKS!!
REFERENCES
• F# Wiki Book - http://en.wikibooks.org/wiki/F_Sharp_Programming	

• Local author, Dave Fancher:The Book of F# - http://www.davefancher.com	

• The F# Foundation - http://fsharp.org/	

• Reactive Extensions - http://msdn.microsoft.com/en-us/data/gg577609.aspx	

• Xamarin - https://xamarin.com/	

• F# and RX - https://github.com/fsprojects/FSharp.Reactive	

• RX Examples (in C#) - http://rxwiki.wikidot.com/101samples	

• F# For Fun And Profit Blog - http://fsharpforfunandprofit.com/posts/fsharp-in-60-seconds/

More Related Content

What's hot

The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of FlatteryJosé Paumard
 
JavaScript 1 for high school
JavaScript 1 for high schoolJavaScript 1 for high school
JavaScript 1 for high schooljekkilekki
 
Being Dangerous with Twig
Being Dangerous with TwigBeing Dangerous with Twig
Being Dangerous with TwigRyan Weaver
 
Wait, IPython can do that?! (30 minutes)
Wait, IPython can do that?! (30 minutes)Wait, IPython can do that?! (30 minutes)
Wait, IPython can do that?! (30 minutes)Sebastian Witowski
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of FlatteryJosé Paumard
 
Swift Bengaluru Meetup slides
Swift Bengaluru Meetup slidesSwift Bengaluru Meetup slides
Swift Bengaluru Meetup slidesPushkar Kulkarni
 
AutoIt for the rest of us - handout
AutoIt for the rest of us - handoutAutoIt for the rest of us - handout
AutoIt for the rest of us - handoutBecky Yoose
 
Hasktut
HasktutHasktut
Hasktutkv33
 
Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)Scott Wlaschin
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumMatthias Noback
 
Elixir and Phoenix for Rubyists
Elixir and Phoenix for RubyistsElixir and Phoenix for Rubyists
Elixir and Phoenix for RubyistsBrooklyn Zelenka
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1José Paumard
 

What's hot (20)

The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
Elixir
ElixirElixir
Elixir
 
JavaScript 1 for high school
JavaScript 1 for high schoolJavaScript 1 for high school
JavaScript 1 for high school
 
Being Dangerous with Twig
Being Dangerous with TwigBeing Dangerous with Twig
Being Dangerous with Twig
 
Wait, IPython can do that?! (30 minutes)
Wait, IPython can do that?! (30 minutes)Wait, IPython can do that?! (30 minutes)
Wait, IPython can do that?! (30 minutes)
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
Wait, IPython can do that?
Wait, IPython can do that?Wait, IPython can do that?
Wait, IPython can do that?
 
Swift Bengaluru Meetup slides
Swift Bengaluru Meetup slidesSwift Bengaluru Meetup slides
Swift Bengaluru Meetup slides
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
AutoIt for the rest of us - handout
AutoIt for the rest of us - handoutAutoIt for the rest of us - handout
AutoIt for the rest of us - handout
 
The Joy Of Ruby
The Joy Of RubyThe Joy Of Ruby
The Joy Of Ruby
 
Hasktut
HasktutHasktut
Hasktut
 
Ruby Gotchas
Ruby GotchasRuby Gotchas
Ruby Gotchas
 
Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup Belgium
 
Elixir and Phoenix for Rubyists
Elixir and Phoenix for RubyistsElixir and Phoenix for Rubyists
Elixir and Phoenix for Rubyists
 
Swift 2
Swift 2Swift 2
Swift 2
 
Enumerable
EnumerableEnumerable
Enumerable
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1
 
Python
PythonPython
Python
 

Similar to F# and Reactive Programming for iOS

Similar to F# and Reactive Programming for iOS (20)

ppt7
ppt7ppt7
ppt7
 
ppt2
ppt2ppt2
ppt2
 
name name2 n
name name2 nname name2 n
name name2 n
 
test ppt
test ppttest ppt
test ppt
 
name name2 n
name name2 nname name2 n
name name2 n
 
ppt21
ppt21ppt21
ppt21
 
name name2 n
name name2 nname name2 n
name name2 n
 
ppt17
ppt17ppt17
ppt17
 
ppt30
ppt30ppt30
ppt30
 
name name2 n2.ppt
name name2 n2.pptname name2 n2.ppt
name name2 n2.ppt
 
ppt18
ppt18ppt18
ppt18
 
Ruby for Perl Programmers
Ruby for Perl ProgrammersRuby for Perl Programmers
Ruby for Perl Programmers
 
ppt9
ppt9ppt9
ppt9
 
name name2 n2
name name2 n2name name2 n2
name name2 n2
 
Workshop Swift
Workshop Swift Workshop Swift
Workshop Swift
 
Functional Programming in F#
Functional Programming in F#Functional Programming in F#
Functional Programming in F#
 
Phyton Learning extracts
Phyton Learning extracts Phyton Learning extracts
Phyton Learning extracts
 
Python Part 1
Python Part 1Python Part 1
Python Part 1
 
Swift Programming
Swift ProgrammingSwift Programming
Swift Programming
 
Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987
 

More from Brad Pillow

GraphQL And Relay Modern
GraphQL And Relay ModernGraphQL And Relay Modern
GraphQL And Relay ModernBrad Pillow
 
GraphQL And Relay Modern
GraphQL And Relay ModernGraphQL And Relay Modern
GraphQL And Relay ModernBrad Pillow
 
GraphQL With Relay Part Deux
GraphQL With Relay Part DeuxGraphQL With Relay Part Deux
GraphQL With Relay Part DeuxBrad Pillow
 
GraphQL IndyJS April 2016
GraphQL IndyJS April 2016GraphQL IndyJS April 2016
GraphQL IndyJS April 2016Brad Pillow
 
Introduction to Xamarin.Forms
Introduction to Xamarin.FormsIntroduction to Xamarin.Forms
Introduction to Xamarin.FormsBrad Pillow
 
Life In The Fast Lane: August 2014 Indy QS Meetup Presentation
Life In The Fast Lane: August 2014 Indy QS Meetup PresentationLife In The Fast Lane: August 2014 Indy QS Meetup Presentation
Life In The Fast Lane: August 2014 Indy QS Meetup PresentationBrad Pillow
 
How To: Mobile "Hello World" With Xamarin and VS-2013
How To: Mobile "Hello World" With Xamarin and VS-2013How To: Mobile "Hello World" With Xamarin and VS-2013
How To: Mobile "Hello World" With Xamarin and VS-2013Brad Pillow
 

More from Brad Pillow (7)

GraphQL And Relay Modern
GraphQL And Relay ModernGraphQL And Relay Modern
GraphQL And Relay Modern
 
GraphQL And Relay Modern
GraphQL And Relay ModernGraphQL And Relay Modern
GraphQL And Relay Modern
 
GraphQL With Relay Part Deux
GraphQL With Relay Part DeuxGraphQL With Relay Part Deux
GraphQL With Relay Part Deux
 
GraphQL IndyJS April 2016
GraphQL IndyJS April 2016GraphQL IndyJS April 2016
GraphQL IndyJS April 2016
 
Introduction to Xamarin.Forms
Introduction to Xamarin.FormsIntroduction to Xamarin.Forms
Introduction to Xamarin.Forms
 
Life In The Fast Lane: August 2014 Indy QS Meetup Presentation
Life In The Fast Lane: August 2014 Indy QS Meetup PresentationLife In The Fast Lane: August 2014 Indy QS Meetup Presentation
Life In The Fast Lane: August 2014 Indy QS Meetup Presentation
 
How To: Mobile "Hello World" With Xamarin and VS-2013
How To: Mobile "Hello World" With Xamarin and VS-2013How To: Mobile "Hello World" With Xamarin and VS-2013
How To: Mobile "Hello World" With Xamarin and VS-2013
 

Recently uploaded

Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 

Recently uploaded (20)

Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 

F# and Reactive Programming for iOS

  • 1. F# AND REACTIVE PROGRAMMING FOR IOS Presented at Indy CocoaHeads, May 2014 Brad Pillow, PillowSoft LLC www.pillowsoft.com https://github.com/pillowsoft twitter: @BradPillow
  • 2. OVERVIEW • What’s new in Xamarin for F# and iOS • What is F# • What is RX (Reactive Extensions) • Using both on iOS It’s going to be a very high-level overview….
  • 3. WHAT'S NEW IN XAMARIN • Support for latest iOS • IDE improvements • Speed/memory footprint optimizations • Generics and JIT issues largely fixed • More PCL (portable class library) support • Soon to have “shared project” support • Component for portable RX support • Most importantly to me, F# support
  • 4. POSSIBLE TARGETS • iOS: iPhone, iPad • Mac Desktop • Android:Android phones,Android tablets, Google Glasses,Amazon FireTV,Android Watches With Xamarin: With Visual Studio: • Windows Store & Desktop • Windows Phones With FunScript or WebSharper: • Web & Web Apps
  • 5. MY FIRST FUNCTIONAL LANGUAGE • Back in 1976 started using APL -The Array Programming Language, developed by IBM in the 60’s (over 1/2 a century ago!) • Now experiencing a minor resurgence (see J Language) • I like to call it “programming in the language of the ancients” for Stargate Fans • Example, find all prime numbers from 1 to R: • (~R∊R∘.×R)/R←1↓ιR
  • 6. WHY DOTHEY CALL IT FUNCTIONAL? The name functional comes from mathematics. If we think about pure math functions like: f(x) = sin(x) we know that for any value of x, we will always get the same value for f(x) when we do the computation.This allows us to reason better about our function, avoid the complications of mutation and state, and do optimizations like memoization.
  • 7. F# AND RX LEARNING CURVE • First time I tried F# I just didn’t get it • I tried writing OOP style • That’s does not work! • Same with RX • Go with the grain and you’ll have some wonderful aha moments
  • 8. THE BASICS • Type Inference • ImmutableValues vsVariables • Recursion or Loops? • Function Composition Rather than Inheritance • Functions as First-OrderTypes • Pattern Matching • But what about OOP?Yep, backward compatibility… F# is essentially a .Net implementation of OCaml, combining the power and expressive syntax of functional programming with the tens of thousands of classes which make up the .NET class library
  • 9. THE BASICS A Type Inference ! Let the compiler worry about your types and proof checking that your code is correct. Known as Hindley-Milner type inference.The compiler is essentially deriving types by ensuring that everything makes sense.All the goodness of less keystrokes with dynamic typing, with all the power of static typing. Immutable Values versus variables ! Being a functional programming language, F# encourages use of values or immutable variables.You can use mutable variables, but it’s typically a “code smell”.While it may seem inefficient to ignore mutation, researchers have come up with impressive immutable data structures that are fast and share memory.
  • 10. RECURSION OR LOOPS • F# and most functional programming languages prefer recursion over looping, as looping implies mutability • If we recurse, then we are typically passing values up and down through our recursion…values mean immutability • Fib in recursive form: let rec fib n = if n <= 2 then 1 else fib (n - 1) + fib (n - 2) • Recursive functions can sometimes be hard to understand • You will typical use fold, unfold and other functional variants to replace recursing let data = [("Cats",4); ("Dogs",5); ("Mice",3); ("Elephants",2)] let count = List.fold (fun acc (nm,x) -> acc+x) 0 data printfn "Total number of animals: %d" count
  • 11. Function Composition Rather than Inheritance // create an "adder" by partial application of add let add42 = (+) 42 // partial application add42 1 add42 3 ! // create a new list by applying the add42 function to each element [1;2;3] |> List.map add42 ! // create a "tester" by partial application of "less than" let twoIsLessThan = (<) 2 // partial application twoIsLessThan 1 twoIsLessThan 3 ! // filter each element with the twoIsLessThan function [1;2;3] |> List.filter twoIsLessThan ! // create a "printer" by partial application of printfn let printer = printfn "printing param=%i" ! // loop over each element and call the printer function [1;2;3] |> List.iter printer
  • 12. Functions as First-OrderTypes F# liberally uses functions as types and it is a basic component of using a powerful technique called higher order functions.A higher-order function is a function that takes another function as a parameter, or a function that returns another function as a value, or a function which does both. ! The Composition Function (<< operator) In algebra, the composition function is defined as compose(f, g, x) = f(g(x)), denoted f o g. ! let f x = x*x let g x = -x/2.0 + 5.0 let fog = f << g Console.WriteLine(fog 0.0) // 25 Console.WriteLine(fog 1.0) // 20.25 ! The Pipeline Function ( |> operator) The pipeline operator, |> , is one of the most important operators in F#. Here is how it is defined: let inline (|>) x f = f x ! It allows us to write: [1 ;2; 3; 4; ] |> List.filter (fun e -> e % 2 = 0) |> List.map (fun v -> v * v) rather than: List.map (fun v -> v * v) (List.filter (fun e -> e % 2 = 0) [1 ;2; 3; 4; ]) The “pipeline” notation is much easier to read and conveys meaning better.
  • 13. QUICK INTROTO F# VARIABLES…SORT OF // single line comments use a double slash (* multi line comments use (* . . . *) pair ! -end of multi line comment- *) ! //The "let" keyword defines an (immutable) value - note that no types are needed let myInt = 5 let myFloat = 3.14 let myString = "hello" let myList = [ “dog”; “cat”; “cow”;] let myArray = [| 1; 2; 3; 4; ] let mySequence = seq { 1..1000 } // lazy sequences Credits: http://fsharpforfunandprofit.com/posts/fsharp-in-60-seconds/
  • 14. QUICK INTROTO F# LISTS let twoToFive = [2;3;4;5] // Square brackets create a list with // semicolon delimiters. let oneToFive = 1 :: twoToFive // :: creates list with new 1st element ! // The result is [1;2;3;4;5] ! let zeroToFive = [0;1] @ twoToFive // @ concats two lists ! ! // NOTE: commas are never used as delimiters, only semicolons !
  • 15. QUICK INTROTO F# FUNCTIONS //The "let" keyword also defines a named function. let square x = x * x // Note that no parens are used. square 3 // Now run the function.Again, no parens. ! let add x y = x + y // don't use add (x,y)! It means something // completely different. add 2 3 // Now run the function. ! // to define a multiline function, just use indents. No semicolons needed. let evens list = let isEven x = x%2 = 0 // Define "isEven" as a sub function List.filter isEven list // List.filter is a library function // with two parameters: a boolean function // and a list to work on ! evens oneToFive // Now run the function
  • 16. QUICK INTROTO F# MORE FUNCTIONS //You can use parens to clarify precedence. In this example, // do "map" first, with two args, then do "sum" on the result. // Without the parens, "List.map" would be passed as an arg to List.sum let sumOfSquaresTo100 = List.sum ( List.map square [1..100] ) ! //You can pipe the output of one operation to the next using "|>" // Here is the same sumOfSquares function written using pipes let sumOfSquaresTo100piped = [1..100] |> List.map square |> List.sum // "square" was defined earlier ! // you can define lambdas (anonymous functions) using the "fun" keyword let sumOfSquaresTo100withFun = [1..100] |> List.map (fun x->x*x) |> List.sum ! // In F# there is no "return" keyword.A function always // returns the value of the last expression used.
  • 17. QUICK INTROTO F# PATTERN MATCHING // Match..with.. is a supercharged case/switch statement. let simplePatternMatch = let x = "a" match x with | "a" -> printfn "x is a" | "b" -> printfn "x is b" | _ -> printfn "x is something else" // underscore matches anything ! // Some(..) and None are roughly analogous to Nullable wrappers let validValue = Some(99) let invalidValue = None ! // In this example, match..with matches the "Some" and the "None", // and also unpacks the value in the "Some" at the same time. let optionPatternMatch input = match input with | Some i -> printfn "input is an int=%d" i | None -> printfn "input is missing" ! optionPatternMatch validValue optionPatternMatch invalidValue
  • 18. QUICK INTROTO F# DATATYPES //tuples are quick 'n easy anonymous types let twoTuple = 1, 2 let threeTuple = “a", 2, true ! //record types have named fields type Person = {First:string; Last:string} let person1 = {First="john"; Last="Doe"} ! //union types have choices type Temp = | DegreesC of float | DegreesF of float let temp = DegreesF 98.6 ! //types can be combined recursively in complex ways type Employee = | Worker of Person | Manager of Employee list let jdoe = { First=“John"; Last=“Doe" } let worker = Worker jdoe
  • 19. QUICK INTROTO F# PRINTING //The printf/printfn functions are similar to the // Console.Write/WriteLine functions in C#….but strongly typed! printfn "Printing an int %i, a float %f, a bool %b" 1 2.0 true printfn "A string %s, and something generic %A" "hello" [1;2;3;4] ! // all complex types have pretty printing built in printfn "twoTuple=%A,nPerson=%A,nTemp=%A,nEmployee=%A" twoTuple person1 temp worker ! //There are also sprintf/sprintfn functions for formatting data // into a string, similar to String.Format.
  • 20. QUICK INTROTO F# THE REPL Definition of REPL: Read-Eval-Print Loop ! The REPL is your friend. Use it heavily while learning F#. Excellent to use when working out small algorithms as well
  • 22. Peter Norvig's Spelling Corrector in F# http://norvig.com/spell-correct.html open System.IO open System.Text.RegularExpressions ! let edits1 (word : string) = let splits = [for i in 0 .. word.Length do yield (word.[0..i-1], word.[i..])] let deletes = [for a, b in splits do if b <> "" then yield a + b.[1..]] let transposes = [for a, b in splits do if b.Length > 1 then yield a + string b.[1] + string b.[0] + b.[2..]] let replaces = [for a, b in splits do for c in 'a'..'z' do if b <> "" then yield a + string c + b.[1..]] let inserts = [for a, b in splits do for c in 'a'..'z' do yield a + string c + b] deletes @ transposes @ replaces @ inserts |> Set.ofList ! let NWORDS = File.ReadAllText "big.txt" |> (Regex "[a-zA-Z]+").Matches |> Seq.cast |> Seq.map (fun (m:Match) -> m.Value.ToLower()) |> Seq.countBy id |> Map.ofSeq ! let known_edits2 word = [for e1 in edits1(word) do for e2 in edits1(e1) do if Map.containsKey e2 NWORDS then yield e2] |> Set.st let known words = [for w in words do if Map.containsKey w NWORDS then yield w] |> Set.ofList ! let (<||>) (first : Lazy<_>) (second : Lazy<_>) : Lazy<_> = lazy(if Set.isEmpty first.Value then second.Value else first.Value) let correct word = (lazy known([word]) <||> lazy known(edits1(word)) <||> lazy known_edits2(word) <||> lazy Set.singleton word).Value |> Seq.sortBy (fun w -> -NWORDS.[w]) |> Seq.head ! // Example correct "speling"
  • 23. WHY RX Integrated LINQ (language Integrated Query) is integrated into the C# language. Unitive Using LINQ allows you to leverage your existing skills for querying data at rest (LINQ to SQL, LINQ to XML or LINQ to objects) to query data in motion.You could think of Rx as LINQ to events. LINQ allows you to transition from other paradigms into a common paradigm. For example you can transition a standard .NET event, an asynchronous method call, aTask or perhaps a 3rd party middleware API into a single common Rx paradigm. By leveraging our existing language of choice and using familiar operators like Select,Where, GroupBy etc, developers can rationalize and communicate designs or code in a common form. Extensible You can extend Rx with your own custom query operators (extension methods). Declarative LINQ allows your code to read as a declaration of what your code does and leaves the how to the implementation of the operators.
  • 24. WHENTO USE RX? Managing events like these is what Rx was built for: • UI events like mouse move, button click • Gestures - see • Domain events like property changed, collection updated, "Order Filled", "Registration accepted" etc. • Infrastructure events like from file watcher, system events • Integration events like a broadcast from a message bus or a push event
  • 25. KEY RX DATATYPES • IObserver<T> - an object that can observe an observable by subscribing to it, receives OnNext, OnError and OnCompleted form observables • IObserverable<T> - an object that can be observed. Allows other to observe it via the Subscribe method. • ISubject<T> - and observer and an observable
  • 26. F# RX OPERATORS add - Create an observer which permanently subscribes to the given observable and which calls the given function for each observation. ! subscribe - Create an observer which subscribes to the given observable and which calls the given function for each observation. ! map - Return an observable which transforms the observations of the source by the given function. ! filter - Return an observable which filters the observations of the source by the given function. ! scan - Return an observables which, for each observer, allocates an item of state and applies the given accumulating function to successive values arising from the input.The returned object will trigger observations for each computed state value, excluding the initial value.The returned object propagates all errors arising from the source and completes when the source completes. ! choose - Return an observable which chooses a projection of observations from the source using the given function. ! split - Return two observables which split the observations of the source by the given function.
  • 27. RX EXAMPLE A let observable = new Subject<int>() ! let mySubscribe = let interested = observable |> Observable.filter (fun x -> x%2=0) interested.Subscribe(fun i -> Console.WriteLine("Hello " + i.ToString())) ! let myYields = observable.OnNext(1) observable.OnNext(2) observable.OnNext(3) observable.OnNext(4)
  • 28. RX EXAMPLE B // Create form let form = new Form(Visible=true,TopMost=true,Text="Event Sample") ! // Create under and over for X andY coordinates let (overEvent, underEvent) = form.MouseDown |> Observable.merge form.MouseMove |> Observable.filter (fun args -> args.Button = MouseButtons.Left) |> Observable.map (fun args -> (args.X, args.Y)) |> Observable.partition (fun (x, y) -> x > 100 && y > 100) ! // Subscribe to each let overSubscription = overEvent |> Observable.subscribe (fun (x, y) -> printfn "Over (%d, %d)" x y) let underSubscription = underEvent |> Observable.subscribe (fun (x, y) -> printfn "Under (%d, %d)" x y) // Much later, clean up overSubscription.Dispose() underSubscription.Dispose()
  • 29. SO MUCH MORE!! • Quotations - your code as meta-data • Computation Expressions - for language oriented programming • Type Providers - type safe access to untyped data • Async - came before C#’s but just as powerful • Agents - for multi-threaded and concurrent apps • Active Patterns - wrap ad hoc values and objects in union-like structures for use in pattern matching. • Units Of Measurement - “unit safe” computing • DSL’s - define more user friendly, internal dsl’s
  • 30. F#TYPE PROVIDERS TWITTER SEARCH IN 10 LINES typeT = FSharp.Data.JsonProvider<"http://search.twitter.com/search.json?q=%23fsharp&lang=en&rpp=1&page=1"> let tweets (tag : string) (since : System.DateTime) = let enc = System.Web.HttpUtility.UrlEncode : string -> string let rec page n = let data =T.Load(sprintf "http://search.twitter.com/search.json?q=%s&rpp=100&page=%d&since=%4d-%02d-%02d" (enc tag) n since.Year since.Month since.Day) seq{ yield! data.Results if not (Seq.isEmpty data.Results) then yield! page (n + 1) } page 1 ! // usage tweets "#fsharp" (System.DateTime.Parse("5/17/2013")) |> Seq.iter ( fun t -> printfn "%-21O %-15s %s" t.CreatedAt t.FromUser t.Text ) Ref: http://fssnip.net/iu
  • 31. SIMPLE IOS EXAMPLE namespace Simple open System open MonoTouch.UIKit open MonoTouch.Foundation open System.Drawing type ContentView ( color : UIColor ) as self = inherit UIView () do self.BackgroundColor < - color type SimpleController ( ) = inherit UIViewController () override this.ViewDidLoad () = this.View <- new ContentView(UIColor.Blue) [<Register ("AppDelegate")>] type AppDelegate () = inherit UIApplicationDelegate () let window = new UIWindow (UIScreen.MainScreen.Bounds) // This method is invoked when the application is ready to run. override this.FinishedLaunching (app, options) = let viewController = new SimpleController() viewController.Title <- "F# Rocks" let navController = new UINavigationController(viewController) window.RootViewController <- navController window.MakeKeyAndVisible () true module Main = [<EntryPoint>] let main args = UIApplication.Main (args, null, "AppDelegate") 0 Credits: http://www.knowing.net/index.php/2013/11/13/f-ios-program-39-lines-of-code/
  • 32. IOS EXAMPLE WITH RX member this.Setup() = let WIDTH = 32.0f ! let chars = " F# reacts to events!" |> Seq.map (fun c -> new UILabel( Text = c.ToString(System.Globalization.CultureInfo.InvariantCulture), Frame = RectangleF(100.f, 100.f, 24.f, 24.f), BackgroundColor = UIColor.Clear, TextAlignment = UITextAlignment.Center, TextColor = UIColor.White, Font = UIFont.FromName("courier", 24.0f) )) |> Seq.toArray ! ! do for tb in chars do this.AddSubview(tb) ! this.AddSubview( new UILabel( Text = "Hello World!", Frame = RectangleF(50.f, 50.f, 400.f, 50.f), BackgroundColor = UIColor.Clear, TextAlignment = UITextAlignment.Left, TextColor = UIColor.White, Font = UIFont.FromName("courier", 32.0f) )); ! this.BackgroundColor <- color this.UserInteractionEnabled <- true this.MultipleTouchEnabled <- true ! touchMoveEvent |> Observable.add (fun p -> async { for i in 0..chars.Length-1 do do! Async.Sleep(90) this.UpdateLabelPosition(chars.[i], p, i) } |> Async.StartImmediate ) |> ignore
  • 33. VIEWMODEL FORTIPCALC UI type MainViewModel() = let payCommand = new ReactiveCommand() let _ = payCommand.Subscribe(fun (boolVal) -> printfn "Paid") ! let subTotalText = new ReactiveProperty<string>() let subTotal = new ReactiveProperty<float>() let tipPercent = new ReactiveProperty<float>() let calculatedTip = dependentsToReactiveProperty<float, float, float> subTotal tipPercent (fun x y -> x * (y / 100.0)) let calculatedTotal = dependentsToReactiveProperty<float, float, float> subTotal calculatedTip (fun x y -> x + y) ! member this.Subtotal with get() = subTotal member this.TipPercent with get() = tipPercent member this.CalculatedTip with get() = calculatedTip member this.CalculatedTotal with get() = calculatedTotal member this.PayCommand with get() = payCommand ! member this.InputText with get () = inputText member this.DisplayText with get() = displayText member this.ReplaceTextCommand with get() = replaceTextCommand
  • 34. DSL FORVIEW A this.mainModel <- new MainViewModel() ! let payButton = Button (text = "Click Me!") let subtotalLabel = Label (text = "Subtotal:") let subtotalTextField = TextField () let tipPercentLabel = Label (text = "Tip Percent:") let tipPercentTextField = TextField () let tipPercentSlider = Slider(min = 0., max = 100.) let totalLabel = Label (text = "Total:") let totalValueTextField = TextField () ! let tipView = View(content = [ subtotalLabel; subtotalTextField; tipPercentSlider; tipPercentLabel; tipPercentTextField; totalLabel; totalValueTextField; payButton; loadTemplateButton; loadMarkdownButton; webView; ]) ! let _ = this.mainModel.TipPercent.Subscribe(fun f -> printfn "slider moved to %f" f) let _ = this.mainModel.Subtotal.Subscribe(fun f -> printfn “sub-total is %f" f) ! let altUIBindings = [ Command(payButton, this.mainModel.PayCommand ); Command(loadTemplateButton, loadTemplateCommand ); Command(loadMarkdownButton, loadMarkdownCommand ); ValueToFromFloat(tipPercentSlider, this.mainModel.TipPercent); ValueToFromString(tipPercentTextField, this.mainModel.TipPercent |> floatToStringProperty); ValueToString(subtotalTextField, this.mainModel.Subtotal |> floatToStringProperty) ValueFromString(totalValueTextField, this.mainModel.CalculatedTotal |> floatToStringProperty) ]
  • 35. DSL FORVIEW B let layoutConstraints = [ UIConstraint( sprintf "|-[%s]-[%s]-[%s]-|" tipPercentSlider.Id tipPercentLabel.Id tipPercentTextField.Id, [LayoutAlignOption.AlignAllBaseline]); UIConstraint( sprintf "[%s]-[%s]-|" totalLabel.Id totalValueTextField.Id, [LayoutAlignOption.AlignAllBaseline]); UIConstraint( sprintf "[%s]-[%s]-|" subtotalLabel.Id subtotalTextField.Id, [LayoutAlignOption.AlignAllBaseline]); UIConstraint( sprintf "V:|-[%s]" subtotalLabel.Id); UIConstraint( sprintf "V:[%s]-[%s]" subtotalLabel.Id tipPercentLabel.Id); UIConstraint( sprintf "V:[%s]-[%s]" tipPercentLabel.Id totalLabel.Id); UIConstraint( sprintf "V:[%s]-[%s]-[%s]" subtotalLabel.Id tipPercentLabel.Id totalLabel.Id, [LayoutAlignOption.AlignAllRight]); UIConstraint( sprintf "[%s(>=70)]" tipPercentTextField.Id); UIConstraint( sprintf "V:[%s(>=20)]" tipPercentTextField.Id); UIConstraint( sprintf "V:[%s(==%s)]" subtotalTextField.Id tipPercentTextField.Id); UIConstraint( sprintf "V:[%s(==%s)]" totalValueTextField.Id tipPercentTextField.Id); UIConstraint( sprintf "[%s(==%s)]" tipPercentSlider.Id tipPercentTextField.Id); UIConstraint( sprintf "V:[%s]-[%s]" totalLabel.Id payButton.Id); ! UIConstraint( sprintf "V:[%s]-|" webView.Id); UIConstraint( sprintf "|-[%s]-|" webView.Id); UIConstraint( sprintf "V:[%s]-[%s]-[%s]-[%s]" payButton.Id loadTemplateButton.Id loadMarkdownButton.Id webView.Id, [LayoutAlignOption.AlignAllCenterX]); UIConstraint(payButton).WithSameCenterX(tipView); ] let viewSpec = { content = tipView; layout = layoutConstraints; bindings = altUIBindings } let viewFactory = UIFactory(viewSpec) let mainView = viewFactory.Build() ! this.ContentView <- mainView ()
  • 36. WHYYOU SHOULD INVESTIGATE F# & RX • You like Python and wish it was a statically typed language • You like functional languages like Lisp, but have gone insane looking at too many parenthesis • You like Objective-C, C# or C++, but feel there just has to be a better way to express your ideas • You like math and see to elegance and beauty in function composition, immutability, folds, monoids, etc. • You want to use one language and yet target an amazing variety of devices and platforms with native performing code
  • 37. WARNING!!! It’s addictive! Don’t believe me? Follow #FSharp onTwitter. THANKS!!
  • 38. REFERENCES • F# Wiki Book - http://en.wikibooks.org/wiki/F_Sharp_Programming • Local author, Dave Fancher:The Book of F# - http://www.davefancher.com • The F# Foundation - http://fsharp.org/ • Reactive Extensions - http://msdn.microsoft.com/en-us/data/gg577609.aspx • Xamarin - https://xamarin.com/ • F# and RX - https://github.com/fsprojects/FSharp.Reactive • RX Examples (in C#) - http://rxwiki.wikidot.com/101samples • F# For Fun And Profit Blog - http://fsharpforfunandprofit.com/posts/fsharp-in-60-seconds/