Slide 1

Slide 1 text

@yot88 F# FOR JAVA PROGRAMMERS F# JAVA

Slide 2

Slide 2 text

@yot88 WHAT IS F# ? λDifferences between Java and F# λ Concise syntax λ Type inference λ Different defaults λ Different philosophy λSpecial to F# λ Functional-first λ Algebraic type system λ Interactivity

Slide 3

Slide 3 text

@yot88 WHAT IS F# ? λFunctional language derived from OCaml λDeveloped by Microsoft Research λ Shipped with Visual Studio in 2010 λOpen source λCross platform λFunctional language on .NET

Slide 4

Slide 4 text

@yot88 SYNTAX

Slide 5

Slide 5 text

@yot88 Immutable Java class public class Person { private final String name; private final Date birthday; public Person(String name, Date birthday) { this.name = name; this.birthday = birthday; } public String getName() { return name; } public Date getBirthday() { return birthday; } }

Slide 6

Slide 6 text

@yot88 Do we really need curly braces ? INDENTATION instead of curly braces public class Person { private final String name; private final Date birthday; public Person(String name, Date birthday) { this.name = name; this.birthday = birthday; } public String getName() { return name; } public Date getBirthday() { return birthday; } }

Slide 7

Slide 7 text

@yot88 Use = to start blocks public class Person = private final String name; private final Date birthday; public Person(String name, Date birthday) = this.name = name; this.birthday = birthday; public String getName() = return name; public Date getBirthday() = return birthday; INDENTATION instead of curly braces

Slide 8

Slide 8 text

@yot88 AUTOMATICALLY create BACKING FIELDS from constructor parameters public class Person = private final String name; private final Date birthday; public Person(String name, Date birthday) = this.name = name; this.birthday = birthday; public String getName() = return name; public Date getBirthday() = return birthday; A lot of duplication

Slide 9

Slide 9 text

@yot88 public class Person = public Person(String name, Date birthday) = public String getName() = return name; public Date getBirthday() = return birthday; Use constructor params directly AUTOMATICALLY create BACKING FIELDS from constructor parameters

Slide 10

Slide 10 text

@yot88 MERGE THE PRIMARY CONSTRUCTOR WITH THE CLASS DEFINITION public class Person(String name, Date birthday) = public String getName() = return name; public Date getBirthday() = return birthday; Merge constructor with the class definition

Slide 11

Slide 11 text

@yot88 LESS SYNTAX NOISE public class Person(String name, Date birthday) = public String getName() = return name; public Date getBirthday() = return birthday; Why do we need semi-colons ?

Slide 12

Slide 12 text

@yot88 LESS SYNTAX NOISE public class Person(String name, Date birthday) = public String getName() = return name public Date getBirthday() = return birthday No more semi-colons

Slide 13

Slide 13 text

@yot88 NO“RETURN”NEEDED public class Person(String name, Date birthday) = public String getName() = return name public Date getBirthday() = return birthday F# is an expression-oriented language

Slide 14

Slide 14 text

@yot88 The return is implicit for the last line in a block public class Person(String name, Date birthday) = public String getName() = name public Date getBirthday() = birthday NO“RETURN”NEEDED

Slide 15

Slide 15 text

@yot88 MEMBERS ARE PUBLIC BY DEFAULT Properties are immutable public class Person(String name, Date birthday) = public String getName() = name public Date getBirthday() = birthday

Slide 16

Slide 16 text

@yot88 NO GET IN F# class Person(String name, Date birthday) = String getName() = name Date getBirthday() = birthday class Person(String name, Date birthday) = String Name = name Date Birthday = birthday

Slide 17

Slide 17 text

@yot88 TYPE INFERENCE Why do we have to repeat the types? Can't the compiler figure it out for us? class Person(String name, Date birthday) = String Name = name Date Birthday = birthday

Slide 18

Slide 18 text

@yot88 Type inference Remove types Indicates they are class members class Person(String name, Date birthday) = Name = name Birthday = birthday class Person(String name, Date birthday) = member this.Name = name member this.Birthday = birthday

Slide 19

Slide 19 text

@yot88 Type inference class Person(String name, Date birthday) = member this.Name = name member this.Birthday = birthday member this.Age = var timeDiff = new Date().getTime() - birthday.getTime() var daysDiff = TimeUnit.DAYS.convert(timeDiff, TimeUnit.MILLISECONDS) daysDiff / 365 Define method the same way

Slide 20

Slide 20 text

@yot88 TYPE ANNOTATION In F#, types come after name class Person(name: string, birthday: Date) = member this.Name = name member this.Birthday = birthday member this.Age = var timeDiff = new Date().getTime() - birthday.getTime() var daysDiff = TimeUnit.DAYS.convert(timeDiff, TimeUnit.MILLISECONDS) daysDiff / 365

Slide 21

Slide 21 text

@yot88 DIFFERENT KEYWORDS In java, we use class and var class Person(name: string, birthday: Date) = member this.Name = name member this.Birthday = birthday member this.Age = var timeDiff = new Date().getTime() - birthday.getTime() var daysDiff = TimeUnit.DAYS.convert(timeDiff, TimeUnit.MILLISECONDS) daysDiff / 365

Slide 22

Slide 22 text

@yot88 DIFFERENT KEYWORDS In F#, we use type and let type Person(name: string, birthday: Date) = member this.Name = name member this.Birthday = birthday member this.Age = let timeDiff = new Date().getTime() - birthday.getTime() let daysDiff = TimeUnit.DAYS.convert(timeDiff, TimeUnit.MILLISECONDS) daysDiff / 365

Slide 23

Slide 23 text

@yot88 FP SYNTAX : Separate data from the functions Define record types Define a function that acts on the type Functions have spaces between parameters // Inferred types of the function age : Person -> int

Slide 24

Slide 24 text

FROM 21 TO 6 LINES OF CODE

Slide 25

Slide 25 text

@yot88 COMPOSITION Compose new functions by using >>

Slide 26

Slide 26 text

@yot88 PIPING Pipe functions with |>

Slide 27

Slide 27 text

@yot88 TYPE INFERENCE

Slide 28

Slide 28 text

TYPE INFERENCE Inferred type of doSomething : val doSomething : f:(int -> string) -> x:int -> string x must be an int y must be a string f must be a ‘int -> string’ function type of f type of x return type

Slide 29

Slide 29 text

@yot88 LESS NOISE, MORE LOGIC // C# code public IEnumerable> GroupBy( IEnumerable source, Func keySelector ) { ... } let groupBy source keySelector = …

Slide 30

Slide 30 text

@yot88 DIFFERENT DEFAULTS

Slide 31

Slide 31 text

@yot88 DIFFERENT DEFAULTS λImmutable by default λmutable is special case λNon-null types/classes by default λNullable is special case λStructural equality by default λreference equality is special case λEverything must be initialized

Slide 32

Slide 32 text

@yot88 IMMUTABILITY BY DEFAULT Error x is not mutable Use mutable keyword

Slide 33

Slide 33 text

@yot88 NOT NULLABLE BY DEFAULT Must be explicit on the type []

Slide 34

Slide 34 text

@yot88 STRUCTURAL EQUALITY No more getHashCode & equals to write

Slide 35

Slide 35 text

@yot88 ALGEBRAIC TYPE SYSTEMS

Slide 36

Slide 36 text

@yot88 TYPE != CLASS A type is a name for a set of things

Slide 37

Slide 37 text

@yot88 TYPE != CLASS

Slide 38

Slide 38 text

@yot88 F# TYPES CAN BE COMPOSED New types are built from smaller types using: AND OR Discriminated unions

Slide 39

Slide 39 text

F# TYPES CAN BE COMPOSED Discriminated unions Each component type (called a union case) must be tagged with a label (called a case identifier or tag) so that they can be told apart (“discriminated”). The labels can be any identifier you like, but must start with an uppercase letter.

Slide 40

Slide 40 text

@yot88 REAL LIFE EXAMPLE λWe accept three forms of payment: λ Cash, Check, or Card. λFor Cash we don't need any extra information λFor Checks we need a check number λFor Cards we need a card type and card number

Slide 41

Slide 41 text

REAL LIFE EXAMPLE We accept three forms of payment: Cash, Check, or Card. For Checks we need a check number For Cards we need a card type and card number OR type Primitive type AND type

Slide 42

Slide 42 text

REAL LIFE EXAMPLE Types are executable documentation Discriminated Unions are a powerful tool for mapping intuitive types to a domain. Help code correctness by making illegal states unrepresentable

Slide 43

Slide 43 text

REAL LIFE EXAMPLE Manipulate collections amount 57.000000 amount 250.000000 Ignore to throw away the result

Slide 44

Slide 44 text

REAL LIFE EXAMPLE Pattern matching on inner fields https://github.com/swlaschin/DomainModelingMadeFunctional/tree/master/src/OrderTakingEvolved

Slide 45

Slide 45 text

HOW SHOULD I ORGANIZE MY CODE IF I DON’T USE CLASSES? Use modules not classes There are three common patterns for mixing types and functions together Declare Types in the SAME MODULE as the functions. Declare Types SEPARATELY from the functions but in the SAME FILE.

Slide 46

Slide 46 text

Type declared separately from the functions and in a different file Containing type definitions only. HOW SHOULD I ORGANIZE MY CODE IF I DON’T USE CLASSES?

Slide 47

Slide 47 text

@yot88 ALL THE SYNTAX QUICKLY

Slide 48

Slide 48 text

@yot88 F# SYNTAX IN 60 SECONDS

Slide 49

Slide 49 text

@yot88 F# SYNTAX IN 60 SECONDS

Slide 50

Slide 50 text

@yot88 F# SYNTAX IN 60 SECONDS

Slide 51

Slide 51 text

@yot88 F# SYNTAX IN 60 SECONDS

Slide 52

Slide 52 text

@yot88 Comes from Option F# SYNTAX IN 60 SECONDS

Slide 53

Slide 53 text

@yot88 F# SYNTAX IN 60 SECONDS

Slide 54

Slide 54 text

@yot88 F# SYNTAX IN 60 SECONDS

Slide 55

Slide 55 text

@yot88 INTEROP WITH .NET LIBRARIES

Slide 56

Slide 56 text

@yot88 INTEROP λ F# natively supports λ .NET classes λ Interfaces λ Structures λ The interop is very straightforward For example, you can write an interface in C# and have the implementation be done in F#.

Slide 57

Slide 57 text

@yot88 INTEROP Use named parameter to help inference

Slide 58

Slide 58 text

@yot88 GIVE ME THE POWER

Slide 59

Slide 59 text

@yot88 ECOSYSTEM

Slide 60

Slide 60 text

@yot88 FABLE https://fable.io/repl/

Slide 61

Slide 61 text

@yot88 STAY SAFE (Full stack F#) https://github.com/CompositionalIT/SAFE-Dojo/ https://safe-stack.github.io/docs/

Slide 62

Slide 62 text

@yot88 F# INTERACTIVE

Slide 63

Slide 63 text

@yot88 WE CAN START RIGHT NOW λ Using F# for development and DevOps scripts λ Using F# for testing λ Using F# for database related tasks λ Using F# to explore and develop interactively λ Other interesting ways of using F# λ Use F# for parsing λ Use F# for diagramming and visualization λ Use F# for accessing web-based data stores λ Use F# for data science and machine learning -- NO PERMISSION NEEDED https://fsharpforfunandprofit.com/posts/low-risk-ways-to-use-fsharp-at-work/ [] let ``When 2 is added to 2 expect 4``() = Assert.AreEqual(4, 2+2) TRUE FOR ANY OTHER FUNCTIONAL LANGUAGE

Slide 64

Slide 64 text

@yot88 TO GO FURTHER

Slide 65

Slide 65 text

FP AND ARCHITECTURE https://increment.com/software-architecture/primer-on-functional-architecture/

Slide 66

Slide 66 text

@yot88 SCOTT WLASCHIN BIG BOSS OF THE GAME https://fsharpforfunandprofit.com/

Slide 67

Slide 67 text

@yot88 RESOURCES ƛ https://fsharpforfunandprofit.com/ ƛ https://fsharp.org/ ƛ How to start with F# : Low risk ways to use F# at work ƛ https://www.youtube.com/watch?v=PLFl95c-IiU ƛ https://fable.io/ ƛ https://safe-stack.github.io/