Upgrade to Pro — share decks privately, control downloads, hide ads and more …

F# for java programmers

F# for java programmers

With small code examples you will :
* Understand the syntax and philosophy differences between Java & F#
* Different defaults
* Less noise
* Algebraic type systems
* Discriminated unions
* Understand how types are executable documentations
* How it helps correctness by making illegal unrepresentable states

Let’s discover this really good language all together.

Yoan

May 06, 2020
Tweet

More Decks by Yoan

Other Decks in How-to & DIY

Transcript

  1. @yot88
    F#
    FOR JAVA PROGRAMMERS
    F#
    JAVA

    View Slide

  2. @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

    View Slide

  3. @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

    View Slide

  4. @yot88
    SYNTAX

    View Slide

  5. @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;
    }
    }

    View Slide

  6. @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;
    }
    }

    View Slide

  7. @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

    View Slide

  8. @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

    View Slide

  9. @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

    View Slide

  10. @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

    View Slide

  11. @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 ?

    View Slide

  12. @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

    View Slide

  13. @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

    View Slide

  14. @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

    View Slide

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

    View Slide

  16. @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

    View Slide

  17. @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

    View Slide

  18. @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

    View Slide

  19. @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

    View Slide

  20. @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

    View Slide

  21. @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

    View Slide

  22. @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

    View Slide

  23. @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

    View Slide

  24. FROM 21 TO 6 LINES OF CODE

    View Slide

  25. @yot88
    COMPOSITION
    Compose new functions by using >>

    View Slide

  26. @yot88
    PIPING
    Pipe functions with |>

    View Slide

  27. @yot88
    TYPE INFERENCE

    View Slide

  28. 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

    View Slide

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

    View Slide

  30. @yot88
    DIFFERENT DEFAULTS

    View Slide

  31. @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

    View Slide

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

    View Slide

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

    View Slide

  34. @yot88
    STRUCTURAL EQUALITY
    No more getHashCode & equals to write

    View Slide

  35. @yot88
    ALGEBRAIC TYPE SYSTEMS

    View Slide

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

    View Slide

  37. @yot88
    TYPE != CLASS

    View Slide

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

    View Slide

  39. 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.

    View Slide

  40. @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

    View Slide

  41. 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

    View Slide

  42. 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

    View Slide

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

    View Slide

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

    View Slide

  45. 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.

    View Slide

  46. 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?

    View Slide

  47. @yot88
    ALL THE SYNTAX QUICKLY

    View Slide

  48. @yot88
    F# SYNTAX IN 60 SECONDS

    View Slide

  49. @yot88
    F# SYNTAX IN 60 SECONDS

    View Slide

  50. @yot88
    F# SYNTAX IN 60 SECONDS

    View Slide

  51. @yot88
    F# SYNTAX IN 60 SECONDS

    View Slide

  52. @yot88
    Comes from Option
    F# SYNTAX IN 60 SECONDS

    View Slide

  53. @yot88
    F# SYNTAX IN 60 SECONDS

    View Slide

  54. @yot88
    F# SYNTAX IN 60 SECONDS

    View Slide

  55. @yot88
    INTEROP WITH .NET LIBRARIES

    View Slide

  56. @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#.

    View Slide

  57. @yot88
    INTEROP
    Use named parameter to help inference

    View Slide

  58. @yot88
    GIVE ME THE POWER

    View Slide

  59. @yot88
    ECOSYSTEM

    View Slide

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

    View Slide

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

    View Slide

  62. @yot88
    F# INTERACTIVE

    View Slide

  63. @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

    View Slide

  64. @yot88
    TO GO FURTHER

    View Slide

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

    View Slide

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

    View Slide

  67. @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/

    View Slide