functional programming with c#

52
Functional Programming in C#

Upload: eastbanc-tachnologies

Post on 20-Jan-2017

105 views

Category:

Software


2 download

TRANSCRIPT

Page 1: Functional Programming with C#

Functional Programming in C#

Page 2: Functional Programming with C#

What is Functional Programming?

• Side-effect free programming?• Higher order functions?• Use of a functional language like F# / Haskell / Scala?

Page 3: Functional Programming with C#

Functional programming is programming with mathematical

functions.

Page 4: Functional Programming with C#

Problem solved!

Page 5: Functional Programming with C#

What is Functional Programming?

Mathematicalfunction

Class method=

Page 6: Functional Programming with C#

What is Functional Programming?

fReferential transparency: same input – same result

Information about possible inputs and outcomes

Page 7: Functional Programming with C#

What is Functional Programming?

public double Calculate(double x, double y){ return x * x + y * y;}

public long TicksElapsedFrom(int year){ DateTime now = DateTime.Now; DateTime then = new DateTime(year, 1, 1);

return (now - then).Ticks;}

Same input – same result Result is always different

Page 8: Functional Programming with C#

What is Functional Programming?

public static int Divide(int x, int y){ return x / y;}

fInteger

IntegerInteger

1

0

?

DivideByZeroException

Page 9: Functional Programming with C#

Method Signature Honesty

Method signature

All possible inputs

All possible outcomes

Page 10: Functional Programming with C#

Method Signature Honesty

Honest signatureDishonest signature

public static int Divide(int x, int y){ return x / y;}

public static int Divide(int x, NonZeroInteger y){ return x / y.Value;}public static int? Divide(int x, int y){ if (y == 0) return null;

return x / y;}

Page 11: Functional Programming with C#

Mathematical Function

• Honest• Has precisely defined input and output

• Referentially transparent• Doesn’t affect or refer to the global state

Page 12: Functional Programming with C#

Why Functional Programming?

Composable

Easy to reason about

Easier to unit test

Reducing complexity

Page 13: Functional Programming with C#

Immutability

• Immutability• Inability to change data

• State• Data that changes over time

• Side effect• A change that is made to some state

Page 14: Functional Programming with C#

Immutability

Mutable operations

Dishonest code=

Page 15: Functional Programming with C#

Immutability

fInput Output

Side effect

Method signature

Hidden part

Page 16: Functional Programming with C#

Immutability

fInputOutput

Side effect

Method signature

Hidden part

Output 2

Page 17: Functional Programming with C#

Why Does Immutability Matter?

• Increased readability• A single place for validating invariants• Automatic thread safety

Page 18: Functional Programming with C#

How to Deal with Side Effects

Command–query separation principle

Command Query

Produces side effects Side-effect free

Returns void Returns non-void

Page 19: Functional Programming with C#

How to Deal with Side Effects

public class CustomerService { public void Process(string customerName, string addressString) { Address address = CreateAddress(addressString); Customer customer = CreateCustomer(customerName, address); SaveCustomer(customer); }

private Address CreateAddress(string addressString) { return new Address(addressString); }

private Customer CreateCustomer(string name, Address address) { return new Customer(name, address); }

private void SaveCustomer(Customer customer) { var repository = new Repository(); repository.Save(customer); }}

Command

Query

Command

Query

Page 20: Functional Programming with C#

How to Deal with Side Effects

var stack = new Stack<string>();stack.Push("value"); // Commandstring value = stack.Pop(); // Both query and command

Page 21: Functional Programming with C#

How to Deal with Side Effects

Application

Domain logic Mutating state

Generates artifacts Uses artifacts to change the system’s state

Page 22: Functional Programming with C#

How to Deal with Side Effects

Immutable CoreInput Artifacts

Mutable Shell

Page 23: Functional Programming with C#

Exceptions and Readability

public ActionResult CreateEmployee(string name) { try { ValidateName(name); // Rest of the method

return View("Success"); } catch (ValidationException ex) { return View("Error", ex.Message); }}

private void ValidateName(string name) { if (string.IsNullOrWhiteSpace(name)) throw new ValidationException("Name cannot be empty");

if (name.Length > 100) throw new ValidationException("Name is too long");}

Page 24: Functional Programming with C#

Exceptions and Readability

public Employee CreateEmployee(string name){ ValidateName(name);

// Rest of the method}

Page 25: Functional Programming with C#

Exceptions and Readability

Exceptions for flow control

Goto statements=

Page 26: Functional Programming with C#

Exceptions and Readability

Method with exceptions

Mathematical function=

Page 27: Functional Programming with C#

Exceptions and Readability

fInput Output

Exceptions

Method signature

Hidden part

Page 28: Functional Programming with C#

Always prefer return values over exceptions.

Page 29: Functional Programming with C#

Use Cases for Exceptions

• Exceptions are for exceptional situations• Exceptions should signalize a bug• Don’t use exceptions in situations you expect to happen

Page 30: Functional Programming with C#

Use Cases for Exceptions

Validations Exceptional situation=

Page 31: Functional Programming with C#

Primitive Obsession

Primitive obsession stands for using primitive types for

domain modeling.

Page 32: Functional Programming with C#

Drawbacks of Primitive Obsession

public class User{ public string Email { get; }

public User(string email) { Email = email; }}

Page 33: Functional Programming with C#

public class User{ public string Email { get; }

public User(string email) { if (string.IsNullOrWhiteSpace(email)) throw new ArgumentException("Email should not be empty");

email = email.Trim(); if (email.Length > 256) throw new ArgumentException("Email is too long");

if (!email.Contains("@")) throw new ArgumentException("Email is invalid");

Email = email; }}

Drawbacks of Primitive Obsession

Page 34: Functional Programming with C#

Drawbacks of Primitive Obsession

public class Organization{ public string PrimaryEmail { get; }

public Organization(string primaryEmail) { PrimaryEmail = primaryEmail; }}

Page 35: Functional Programming with C#

public class Organization{ public string PrimaryEmail { get; }

public Organization(string primaryEmail) { if (string.IsNullOrWhiteSpace(primaryEmail)) throw new ArgumentException("Email should not be empty");

primaryEmail = primaryEmail.Trim(); if (primaryEmail.Length > 256) throw new ArgumentException("Email is too long");

if (!primaryEmail.Contains("@")) throw new ArgumentException("Email is invalid");

PrimaryEmail = primaryEmail; }}

Drawbacks of Primitive Obsession

Page 36: Functional Programming with C#

Drawbacks of Primitive Obsession

Dishonest signature

public class UserFactory{ public User CreateUser(string email) { return new User(email); }}

public int Divide(int x, int y){ return x / y;}

fstring user

Dishonest signature

Page 37: Functional Programming with C#

Drawbacks of Primitive Obsession

Makes code dishonest

Violates the DRY principle

Page 38: Functional Programming with C#

Wrap primitive types with separate classes

Page 39: Functional Programming with C#

Drawbacks of Primitive Obsession

public class UserFactory{ public User CreateUser(Email email) { return new User(email); }}

public int Divide(int x, NonZeroInteger y){ return x / y;}

femail user

Honest signature Honest signature

Page 40: Functional Programming with C#

Getting Rid of Primitive Obsession

• Removing duplications• Method signature honesty• Stronger type system

Page 41: Functional Programming with C#

The Billion-dollar Mistake

string someString = null;Customer customer = null;Employee employee = null;

Page 42: Functional Programming with C#

The Billion-dollar Mistake

“I call it my billion-dollar mistake. It has caused a billion dollars of pain and damage in the last forty years.”

Tony Hoare

Page 43: Functional Programming with C#

The Billion-dollar Mistake

public class Organization{ public Employee GetEmployee(string name) { /* ... */ }}

public class OrganizationRepository{ public Organization GetById(int id) { /* ... */ }}

Page 44: Functional Programming with C#

The Billion-dollar Mistake

public class MyClassOrNull{ // either null public readonly Null Null; // or actually a MyClass instance public readonly MyClass MyClass; }

public class MyClass{}

Page 45: Functional Programming with C#

The Billion-dollar Mistake

fInteger MyClass

MyClassOrNull

Dishonest

Page 46: Functional Programming with C#

Mitigating the Billion-dollar Mistake

Maybe<T>

Page 47: Functional Programming with C#

Mitigating the Billion-dollar Mistake

public class OrganizationRepository{

public Organization GetById(int id) { /* ... */ }}

Maybe<Organization>

Page 48: Functional Programming with C#

Mitigating the Billion-dollar Mistake

public class OrganizationRepository{ public Maybe<Organization> GetById(int id) { /* ... */ }}

public class Organization{ public Employee GetEmployee(string name) { /* ... */ }}

Page 49: Functional Programming with C#

Mitigating the Billion-dollar Mistake

public class OrganizationRepository{ public Maybe<Organization> GetById(int id) { /* ... */ }}

public static int? Divide(int x, int y){ if (y == 0) return null;

return x / y;}

Honest

Honest

Page 50: Functional Programming with C#

Functional C#

Demo time

Page 51: Functional Programming with C#

Summary

• Functional programming is programming with mathematical functions• Method signature honesty• Referential transparency

• Side effects and exceptions make your code dishonest about the outcome it may produce

• Primitive obsession makes your code dishonest about its input parts

• Nulls make your code dishonest about both its inputs and outputs• Applying Functional Principles in C# Pluralsight course:

https://app.pluralsight.com/courses/csharp-applying-functional-principles

Page 52: Functional Programming with C#

THANK YOU

Vladimir Khorikov @[email protected]