Addendum
Memoization
π‘ Idea: reduce the calculation time of a function
β How to: cache results β next call with same arguments, return cached result
π In practice : function memoizeN from library FSharpPlus
β οΈ Caution : As with any optimization, use it when you need it and check (measure) that it works without any additional inconvenience.
β Not to be confused with lazy expression...
Lazy expression
Syntax sugar to create a .NET Lazy<'T> object from an expression
Expression not evaluated immediately but on 1st request (Thunk)
Interesting for improving performance without overcomplexifying the code
let printAndForward x = printfn $"{x}"; x
let a = lazy (printAndForward "a")
let b = printAndForward "b"
// > b
printfn $"{a.Value} and {b}"
// > a
// > a and b
printfn $"{a.Value} and c"
// > a and cLazy active pattern
Lazy active patternExtracts the value from a Lazy object
Organizing functions
3 ways to organize functions = 3 places to declare them:
Module: function declared within a module π
Nested : function declared inside a value or inside another function
π‘ Encapsulate helpers used just locally
β Parent function parameters accessible to function nested
Method : function defined as a method in a type...
Methods
Defined with the
memberkeyword rather thanletChoice of the self-identifier:
this,me,self,_...Choice of the parameters style:
Tuplified: OOP style
Curried: FP style
Method Examples
Function vs Method
Naming convention
camelCase
PascalCase
Currying
β yes
β if not tuplified nor overridden
Named parameters
β no
β if tuplified
Optional parameters
β no
β if tuplified
Overload
β no
β if tuplified
Parameter inference (declaration)
β Possible
β yes for this, possible for the other parameters
Argument inference (usage)
β yes
β no, object type annotation needed
High-order function argument
β yes
β yes with shorthand member, no with lambda otherwise
inline supported
β yes
β yes
Recursive
β
yes with rec
β yes
Function vs Delegate
We can define a delegate in F# with the syntax:
type Fn = delegate of args: Args -> Return
π A delegate adds a thin layer on top of a function signature, like an object with a single method Invoke:
Pros: we can use named arguments when invoking the delegate
Cons:
extra work to wrap the function (or the method) in the delegate and to execute the function by calling the
Invoke(...)methodcumbersome syntax when there are several parameters, to differentiate between tuple and curried parameters:
Tuple:
type MyFn = delegate of (int * int) -> intCurried:
type MyFn = delegate of int * int -> int
It's not a very common use case in F#.
Interop with the BCL
void method
A .NET void method is seen in Fβ― as returning unit.
Conversely, an Fβ― function returning unit is compiled into a void method.
Equivalent C# based on SharpLab:
Calling a BCL method with N arguments
A .NET method with several arguments is "pseudo-tuplified":
All arguments must be specified (1)
Partial application of parameters is not supported (2)
Calls don't work with a real Fβ― tuple β οΈ (3)
out Parameter - In Cβ―
out Parameter - In Cβ―out used to have multiple output values from a method
β Ex : Int32.TryParse, Dictionary<,>.TryGetValue :
out Parameter - In Fβ―
out Parameter - In Fβ―Output can be consumed as a tuple π
Instantiate a class with new?
new?Calling an overloaded method
Compiler may not understand which overload is being called
Tips: call with named argument
Last updated
Was this helpful?