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.

9489b8d6f2dbdc3e7d26b8702143b86e?s=128

Yoan

May 06, 2020
Tweet

Transcript

  1. 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
  2. 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
  3. 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; } }
  4. 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; } }
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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 ?
  10. 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
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 29.

    @yot88 LESS NOISE, MORE LOGIC // C# code public IEnumerable<IGrouping<TKey,

    TSource>> GroupBy<TSource, TKey>( IEnumerable<TSource> source, Func<TSource, TKey> keySelector ) { ... } let groupBy source keySelector = …
  24. 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
  25. 33.

    @yot88 NOT NULLABLE BY DEFAULT Must be explicit on the

    type [<AllowNullLiteralAttribute>]
  26. 38.

    @yot88 F# TYPES CAN BE COMPOSED New types are built

    from smaller types using: AND OR Discriminated unions
  27. 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.
  28. 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
  29. 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
  30. 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
  31. 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.
  32. 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?
  33. 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#.
  34. 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/ [<Test>] let ``When 2 is added to 2 expect 4``() = Assert.AreEqual(4, 2+2) TRUE FOR ANY OTHER FUNCTIONAL LANGUAGE
  35. 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/