Introduction to F# for the C# developer
Transcript of Introduction to F# for the C# developer
F# for the
C# developer
Nate Peterson@njpetersonpa
Brief intro to F#Thinking functionallyLook at some code
Simple vs. Complex
and
Familiar vs. Unfamiliar
What’s NOT
in this talk
What is F#?
Functional-first language
Strongly typed
let add x y = x + y
add 1 1
F# is more than just a new language
It’s a new way of thinking
Immutability
Side-effect free functions
Functions are first class
let add x y = x + y
let add42 x = add 42 x
add42 1
let add x y = x + y
let add42 = add 42
add42 1
Sum of Squares- C#
public static class SumOfSquaresHelper { public static int Square(int i) { return i * i; }
public static int SumOfSquares(int n) { int sum = 0; for (int i = 1; i <= n; i++) { sum += Square(i); } return sum; } }
Sum of Squares- C# (again)
public static class FunctionalSumOfSquaresHelper { public static int SumOfSquares(int n) { return Enumerable.Range(1, n) .Select(i => i * i) .Sum(); } }
Sum of Squares- F#
let square x = x * x
let sumOfSquares n = [1..n] |> List.map square|> List.sum
sumOfSquares 100
Think about…Concise – no noiseSimple vs. Complex
Familiar vs. Unfamiliar
where are the typeswhere’s the {}
Sum of Squares (evens only)
public static class SumOfSquaresHelper { public static int Square(int i) { return i * i; }
public static int SumOfSquares(int n) { int sum = 0; for (int i = 1; i <= n; i++) { if (i % 2 == 0) { sum += Square(i); } } return sum; } }
public static class FunctionalSumOfSquaresHelper { public static int SumOfSquares(int n) { return Enumerable.Range(1, n) .Select(i => i * i) .Where(i => i % 2 == 0) .Sum(); } }
let square x = x * x
let isEven x = x % 2 = 0
let sumOfSquares n = [1..n] |> List.filter List.map square|> List.filter isEven |> List.sum
sumOfSquares 100
FizzBuzz - C#
public List<string> Create() { var results = new List<string>(); for (var i = 0; i < 100; i++) { results.Add(FizzBuzz(i)); }
return results; }
private static string FizzBuzz(int num) { if (num % 3 == 0 && num % 5 == 0) { return "FizzBuzz"; }
if (num % 3 == 0) { return "Fizz"; }
if (num % 5 == 0) { return "Buzz"; }
return num.ToString(); }
FizzBuzz - C# (again)
public List<string> Create(IEnumerable<int> sequence) { return Enumerable.Range(1, 100).Select(FizzBuzz).ToList(); } private static string FizzBuzz(int num) { if (num % 3 == 0 && num % 5 == 0) { return "FizzBuzz"; }
if (num % 3 == 0) { return "Fizz"; }
if (num % 5 == 0) { return "Buzz"; }
return num.ToString(); }
FizzBuzz - F#
let FizzBuzz number = match number % 3, number % 5 with | 0, 0 -> "FizzBuzz" | 0, _ -> "Fizz" | _, 0 -> "Buzz" | _ -> string number
[1..100]|> List.map FizzBuzz|> List.reduce (sprintf "%s\r\n%s")
Think about…Concise – again
Pattern matching for flow control
Immutable Person – C#
public class Person { public Person(string firstName, string lastName) { } }
public class Person { private string _firstName; private string _lastName;
public Person(string firstName, string lastName) { _firstName = firstName; _lastName = lastName; } }
public class Person { private string _firstName; private string _lastName;
public Person(string firstName, string lastName) { _firstName = firstName; _lastName = lastName; }
public string FirstName { get { return _firstName; } } }
public class Person { private string _firstName; private string _lastName;
public Person(string firstName, string lastName) { _firstName = firstName; _lastName = lastName; }
public string FirstName { get { return _firstName; } }
public string LastName { get { return _lastName; } } }
public class Person { private readonly string _firstName; private readonly string _lastName;
public Person(string firstName, string lastName) { _firstName = firstName; _lastName = lastName; }
public string FirstName { get { return _firstName; } }
public string LastName { get { return _lastName; } } }
Immutable Person – F#
type Person = {FirstName:string; LastName:string}
let nate = {FirstName=“Nate"; LastName=“Peterson"}
Nate Peterson@njpetersonpa