Top Banner
Hello! I am Mikhail Shilkov I am here to talk some Functional Programming and F# You can nd me at @MikhailShilkov and http://mikhail.io
65

Introduction of Functional Programming

Apr 11, 2017

Download

Software

Mikhail Shilkov
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Introduction of Functional Programming

Hello!I am Mikhail Shilkov

I am here to talk some Functional Programming and F#

You can �nd me at @MikhailShilkov and http://mikhail.io

Page 2: Introduction of Functional Programming

Poll

Page 3: Introduction of Functional Programming

AgendaLearn Functional Programming - 45 min

Learn F# - 30 min

Page 4: Introduction of Functional Programming

FunctionalProgramming

Page 5: Introduction of Functional Programming

Here's how it works

PrinciplesConstraints

around yourcode

Bene잷�tsUseful

properties thathold under

theseconstraints

AdoptionSee where

these bene�tsmake thedi�erence

Page 6: Introduction of Functional Programming

PrinciplesHow is functional programming di�erent?

Page 7: Introduction of Functional Programming

Purity

Page 8: Introduction of Functional Programming

Function as mapping

Domain Codomain

Page 9: Introduction of Functional Programming

Determinism

// This is not deterministic public bool IsMoreThanHourAgo(DateTime time) {            var hour = TimeSpan.FromHours(‐1);   return time < DateTime.Now.Add(hour); } 

Page 10: Introduction of Functional Programming

Determinism

// This is deterministic public bool IsMoreThanHourApart(DateTime time, DateTime anotherTime) {            var hour = TimeSpan.FromHours(‐1);   return time < anotherTime.Add(hour); } 

Page 11: Introduction of Functional Programming

No side effects

public class TextCounter {   private int wordCount = 0;   private int charCount = 0;    public void Count(string word)   {     this.WordCount += 1;     this.CharCount += word.Length;   }    public void Print() =>     Console.WriteLine($"Words: {wordCount}, characters: {charCount}"); }

Page 12: Introduction of Functional Programming

No side effects

public class TextCounter {   public Tuple<int, int> Count(string[] word)   {     var wordCount = word.Length;     var charCount = word.Sum(w => w.Length);     return Tuple.Create(wordCount, charCount);   } }

Page 13: Introduction of Functional Programming

Immutability

var importantThing = /*...*/; var result = DoWork(importantThing); // Can I trust my importantThing is unchanged?

Page 14: Introduction of Functional Programming

Totality

Page 15: Introduction of Functional Programming

One more function

Int Int

Page 16: Introduction of Functional Programming

What's wrong here?

Page 17: Introduction of Functional Programming

Int Int

Page 18: Introduction of Functional Programming

public static int sqrtPlus1(int x) {    if (x < 0) throw new ArgumentException(nameof(x));    return Math.Floor(Math.Sqrt(x)) + 1; } 

Page 19: Introduction of Functional Programming

Natural Int

Page 20: Introduction of Functional Programming

Int Complex

Page 21: Introduction of Functional Programming

No Exceptions for control flow

public static int sqrtPlus1(int x) {    if (x < 0) throw new ArgumentException(nameof(x));    return Math.Floor(Math.Sqrt(x)) + 1; } 

Page 22: Introduction of Functional Programming

Strong typesystem

Everything is a type

Page 23: Introduction of Functional Programming

Primitive types

Int String

Page 24: Introduction of Functional Programming

Algebraic Data Types

Int  * Int Byte * Boolean               Int  | String Byte | Boolean

Page 25: Introduction of Functional Programming

Function Types

Int ‐> Int Int[] ‐> String Int ‐> Int ‐> Int (Int ‐> Int ‐> Int) ‐> Int[] ‐> Int

Page 26: Introduction of Functional Programming

Generics

T ‐> U `a[] ‐> `b

Page 27: Introduction of Functional Programming

Side effects

unit String ‐> unit IO[T]

Page 28: Introduction of Functional Programming

No NULLs

public interface IGetThing {     // Can the result be null?     Thing Get(int id); } 

Page 29: Introduction of Functional Programming

No NULLs

public interface IGetThing {     // Hey, result is optional     Option<Thing> Get(int id); } 

Page 30: Introduction of Functional Programming

Making invalid statesunrepresentable

public class Contact  {   public string Name { get; set; }   public EmailInfo Email { get; set; }   public AddressInfo Postal { get; set; } }

Page 31: Introduction of Functional Programming

Making invalid statesunrepresentable

type ContactInfo =    | EmailOnly of EmailInfo   | PostOnly of AddressInfo   | EmailAndPost of EmailInfo * AddressInfo  type Contact = {   Name: string;   Contact: ContactInfo; }

Page 32: Introduction of Functional Programming

BenefitsWhy do we want functional programming?

Page 33: Introduction of Functional Programming

Formal reasoning

Page 34: Introduction of Functional Programming

Referencial transparency

sqrt(mult2(add3(5)) sqrt(mult2(8)) sqrt(16) 4 

Page 35: Introduction of Functional Programming

Control Flow Expression Evaluation

Page 36: Introduction of Functional Programming

Type signature as documentation

int ‐> int Customer ‐> Address U ‐> T[] ‐> U Identifier ‐> Task<Customer>

Page 37: Introduction of Functional Programming

Composition

Page 38: Introduction of Functional Programming

Succinct, concise and precise code

Page 39: Introduction of Functional Programming

Higher Order Functions

var categories = products     .GroupBy(prod => prod.Category)     .Select(prodGroup => new {        prodGroup,          minPrice = prodGroup.Min(p => p.UnitPrice)     })     .Select(t => new {         Category = t.prodGroup.Key,          CheapestProducts = t.prodGroup             .Where(p => p.UnitPrice == t.minPrice)     });

Page 40: Introduction of Functional Programming

Recursion

qsort [] = []  qsort [a] = [a]  qsort (a:as) = let (lesser, greater) = partition a as                in qsort lesser ++ [a] ++ qsort greater

Page 41: Introduction of Functional Programming

Parallelism

Page 42: Introduction of Functional Programming

Testabilty

Page 43: Introduction of Functional Programming

Pure function is the easiest thing totest

Page 44: Introduction of Functional Programming

Functions are intrinsically mockable

Page 45: Introduction of Functional Programming

Parameterized testing

[Test] public void MyTestCase() {     var a = 5;     var b = 10;          var result = target.Add(a, b); 

    result.Should().Be(15); } 

Page 46: Introduction of Functional Programming

Parameterized testing

[TestCase(5, 10, 15)] [TestCase(2, 3, 5)] [TestCase(‐2, 2, 0)] public void MyTestCase(int a, int b, int c) {     var result = target.Add(a, b); 

    result.Should().Be(c); } 

Page 47: Introduction of Functional Programming

Property-based testing

[Property] public void AddToZeroDoesNotChangeTheNumber(int a) {     var result = target.Add(a, 0);     result.Should().Be(a); }  [Property] public void OrderDoesNotMatter(int a, int b) {     var result1 = target.Add(a, b);     var result2 = target.Add(b, a);     result1.Should().Be(result2); }

Page 48: Introduction of Functional Programming

AdoptionDo people use FP in modern applications?

Page 49: Introduction of Functional Programming

Your code should better beSOLID!

Page 50: Introduction of Functional Programming

public class FileStore : IMessageQuery {   private readonly DirectoryInfo workingDirectory;      public FileStore(DirectoryInfo workingDirectory)   {              this.workingDirectory = workingDirectory;   }      

  public string Read(int id)   {              var path = Path.Combine(       this.workingDirectory.FullName,        id + ".txt");     return File.ReadAllText(path);   }  } 

Page 51: Introduction of Functional Programming
Page 52: Introduction of Functional Programming

Domain Driven Design

Page 53: Introduction of Functional Programming

Event Sourcing

Page 54: Introduction of Functional Programming

Event   E

data

Projection   P

data

Event handler 

E[] -> Pfunction

Page 55: Introduction of Functional Programming

Event  E

data

Command  C

data

Commandhandler

 C -> E[]function

Page 56: Introduction of Functional Programming

Actor Frameworks

Page 57: Introduction of Functional Programming

Akka Streams

val counterRunnableGraph: RunnableGraph[Future[Int]] =   tweetsInMinuteFromNow     .filter(_.hashtags contains akkaTag)     .map(t => 1)     .toMat(sumSink)(Keep.right)

Page 58: Introduction of Functional Programming

Apache Hadoop / MapReduce

Page 59: Introduction of Functional Programming

Apache Hadoop / MapReduce

// This class performs the map operation, translating raw input into the key‐value // pairs we will feed into our reduce operation. class TokenizerMapper extends Mapper[Object,Text,Text,IntWritable] {   val one = new IntWritable(1)   val word = new Text      override   def map(key:Object, value:Text, context:Mapper[Object,Text,Text,IntWritable]#Context) = {     for (t <‐  value.toString().split("\\s")) {       word.set(t)       context.write(word, one)     }   } }    // This class performs the reduce operation, iterating over the key‐value pairs // produced by our map operation to produce a result. In this case we just // calculate a simple total for each word seen. class IntSumReducer extends Reducer[Text,IntWritable,Text,IntWritable] {   override   def reduce(key:Text, values:java.lang.Iterable[IntWritable], context:Reducer[Text,IntWritable,Text,IntWritable]#Context) = {     val sum = values.foldLeft(0) { (t,i) => t + i.get }     context.write(key, new IntWritable(sum))   } }    // This class configures and runs the job with the map and reduce classes we've // specified above. object WordCount { 

  def main(args:Array[String]):Int = {     val job = new Job(conf, "word count")     job.setJarByClass(classOf[TokenizerMapper])     job.setMapperClass(classOf[TokenizerMapper])     job.setCombinerClass(classOf[IntSumReducer])     job.setReducerClass(classOf[IntSumReducer])     job.setOutputKeyClass(classOf[Text])     job.setOutputValueClass(classOf[IntWritable])     FileInputFormat.addInputPath(job, new Path(args(0)))     FileOutputFormat.setOutputPath(job, new Path((args(1))))     if (job.waitForCompletion(true)) 0 else 1   } 

}

Page 60: Introduction of Functional Programming

Apache Spark

Page 61: Introduction of Functional Programming

Apache Spark

val sc = new SparkContext(conf) val input =  sc.textFile(inputFile) val words = input.flatMap(line => line.split(" ")) val counts = words.map(word => (word, 1))                   .reduceByKey{case (x, y) => x + y} counts.saveAsTextFile(outputFile)

Page 62: Introduction of Functional Programming

Apache Kafka

Page 63: Introduction of Functional Programming

Wrapping Up

Page 64: Introduction of Functional Programming

Functional Programming is...

Page 65: Introduction of Functional Programming

Thanks!Mikhail Shilkov

Next: Introduction of F#

You can �nd me at @MikhailShilkov and http://mikhail.io