THIS IS ME!
Tomas JanssonManager & Practice Lead .NETBEKK Oslo
@[email protected]/mastojslideshare.net/mastojblog.tomasjansson.com
#2: Separation
"Objects are not data structures. Objects may use data structures; but the manner in which those data structures are used or contained is hidden. This is why data fields are private. From the outside looking in you cannot see any state. All you can see are functions. Therefore Objects are about functions not about state."
Uncle Bob - http://blog.cleancoder.com/uncle-bob/2014/11/24/FPvsOO.html
#2: Separation
"Objects are not data structures. Objects may use data structures; but the manner in which those data structures are used or contained is hidden. This is why data fields are private. From the outside looking in you cannot see any state. All you can see are functions. Therefore Objects are about functions not about state."
Uncle Bob - http://blog.cleancoder.com/uncle-bob/2014/11/24/FPvsOO.html
#3: Null handling
Null References: The Billion Dollar Mistake
- Sir Charles Antony Richard Hoare http://tinyurl.com/TheBillionDollarMistake
#3: Null handling
type Order = {OrderId: int; Total: int}
let getOrder orderId = match orderId with | 0 -> None | _ -> Some { OrderId = orderId Total = 23*orderId }
let printOrder order = match order with | Some o -> printfn "Order id: %i, Total: %i« o.OrderId o.Total | None -> printfn "No order"
#3: Null handling
type Order = {OrderId: int; Total: int}
let getOrder orderId = match orderId with | 0 -> None | _ -> Some { OrderId = orderId Total = 23*orderId }
let printOrder order = match order with | Some o -> printfn "Order id: %i, Total: %i« o.OrderId o.Total | None -> printfn "No order"
Returns Order option
#3: Null handling
type Order = {OrderId: int; Total: int}
let getOrder orderId = match orderId with | 0 -> None | _ -> Some { OrderId = orderId Total = 23*orderId }
let printOrder order = match order with | Some o -> printfn "Order id: %i, Total: %i« o.OrderId o.Total | None -> printfn "No order"
Returns Order option
Explicit null
handling!
#3: Null handling
public class Order{ public int OrderId { get; set; } public int Total { get; set; }}
public Order GetOrder(int orderId){ if (orderId == 0) return null; return new Order() { OrderId = orderId, Total = 23*orderId };}
public void PrintOrder(Order order){ Console.WriteLine("Order id: {0}, Total: {1}", order.OrderId, order.Total);}
#3: Null handling
public class Order{ public int OrderId { get; set; } public int Total { get; set; }}
public Order GetOrder(int orderId){ if (orderId == 0) return null; return new Order() { OrderId = orderId, Total = 23*orderId };}
public void PrintOrder(Order order){ Console.WriteLine("Order id: {0}, Total: {1}", order.OrderId, order.Total);}
How do I differ
success from
failure?
#3: Null handling
public class Order{ public int OrderId { get; set; } public int Total { get; set; }}
public Order GetOrder(int orderId){ if (orderId == 0) return null; return new Order() { OrderId = orderId, Total = 23*orderId };}
public void PrintOrder(Order order){ Console.WriteLine("Order id: {0}, Total: {1}", order.OrderId, order.Total);}
How do I differ
success from
failure?
What about null?
#4: Types
public class Customer { public Guid CustomerId { get; private set; } public string FirstName { get; private set; } public string LastName { get; private set; }
public Customer(Guid customerId, string firstName, string lastName) { CustomerId = customerId; FirstName = firstName; LastName = lastName; }
protected bool Equals(Customer other) { return CustomerId.Equals(other.CustomerId) && string.Equals(FirstName, other.FirstName) && string.Equals(LastName, other.LastName); }
public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; return Equals((Customer) obj); }
public override int GetHashCode() { unchecked { var hashCode = CustomerId.GetHashCode(); hashCode = (hashCode*397) ^ (FirstName != null ? FirstName.GetHashCode() : 0); hashCode = (hashCode*397) ^ (LastName != null ? LastName.GetHashCode() : 0); return hashCode; } }}
#6: Readability
// Version 1let executeCommand command = command |> validate |> log |> execute |> loglet result = executeCommand command
// Version 2let executeCommand = validate >> log >> execute >> loglet result = executeCommand command
#6: Readability
// Version 1public ExecutionResult ExecuteCommand(Command command){ return Log(Execute(Log(Validate(command))));}var result = ExecuteCommand(new Command());
// Version 2public ExecutionResult ExecuteCommand(Command command){ var validationResult = Validate(command); Log(validationResult); var executionResult = Execute(validationResult); Log(executionResult); return executionResult;}var result = ExecuteCommand(new Command());
@simontcousins
@ScottWlaschin
http://tinyurl.com/CyclesInTheWild
http://tinyurl.com/DoesTheLanguageMakeADifference
Cycles
Compared 10 C# projects with 10 F# projects
Compared «top-level» types
Top-level type: “a type that is not nested and which is not compiler generated”
@ScottWlaschin
http://tinyurl.com/CyclesInTheWild
PROJECTS
Mono.Cecil, which inspects programs and libraries in the ECMA CIL format
NUnit
SignalR for real-time web functionality
NancyFx, a web framework
YamlDotNet, for parsing and emitting YAML
SpecFlow, a BDD tool
Json.NET
Entity Framework
ELMAH, a logging framework for ASP.NET
NuGet itself
Moq, a mocking framework
NDepend, a code analysis tool
FSharp.Core, the core F# library.
FSPowerPack.
FsUnit, extensions for NUnit.
Canopy, a wrapper around the Selenium test automation tool.
FsSql, a nice little ADO.NET wrapper.
WebSharper, the web framework.
TickSpec, a BDD tool.
FSharpx, an F# library.
FParsec, a parser library.
FsYaml, a YAML library built on FParsec.
Storm, a tool for testing web services.
Foq, a mocking framework.
C#
F#
Does your language matter?
Application to assist in maintaining the stability and security of the electricity supply in the UK
Existing solution almost fully implemented in C#
Rewritten in F#
@simontcousins
http://tinyurl.com/DoesTheLanguageMakeADifference
“The C# project took five years and peaked at ~8 devs. It never fully implemented all of the contracts.
The F# project took less than a year and peaked at three devs (only one had prior experience with F#). All of the contracts were fully implemented.”
http://tinyurl.com/DoesTheLanguageMakeADifference
THE LANGUAGE YOU USE MAKE A DIFFERENCE
Encapsulated small types
Less top-level dependencies
Less «leaky» abstractions
Types and functions must be defined
Prevents cycles
Encapsulation
Much easier to do in F#
Linear
Generics
http://fsharp.org/
http://www.meetup.com/OsloFSharp/
https://twitter.com/hashtag/fsharp
http://www.peoplevine.com/page/peoplevine-for-startups
Start small, but think
big!
RESOURCES
http://fsharpforfunandprofit.com/
http://tinyurl.com/DoesTheLanguageMakeADifference
http://www.meetup.com/OsloFSharp/ (if you live in Oslo)
http://fsharp.org/
Recommended