First concepts
Last updated
Was this helpful?
Last updated
Was this helpful?
A statement will produce a side effect. An expression will produce a value... and a possible side effect (that we should avoid).
Fβ― is a functional, expression-based language only.
In comparison, Cβ― is an imperative language, based on statements, but includes more and more syntactic sugar based on expressions:
Ternary operator b ? x : y
??
in Cβ― 8 : label ?? "(Empty)"
in Cβ― 6 and 7
switch
expression in Cβ― 8
Conciseness: less visual clutters β more readable
Composability: composing expressions is like composing values
Understanding: no need to know the previous instructions to understand the current one
Testability: pure are easier to test
Predictable: same inputs mean same outputs
Isolated: shorter Arrange/Setup phase in tests, no need for mocks
A function is declared and behaves like a value
We can pass it as parameter or return it from another function (1)
The control flow building blocks are also expressions
if β¦ then/else
, match β¦ with
for β¦ in
, for β¦ to
, while β¦ do
just return "nothing" (2)
Consequences
No void
β Best replaced by the unit
type π
No Early Exit
In C#, you can exit a function with return
and exit a for/while
loop with break
.
In Fβ― these keywords do not exist.
One solution in imperative style is to use mutable variables π
The most recommended and idiomatic solution in functional programming is to use a recursive function π
The ceremony is correlated to the typing weakness
JS
Low (dynamic typing)
Γ
Low
Cβ―
Medium (static nominal)
Low
High
TS
Strong (static structural + ADT)
Medium
Medium
Fβ―
Strong (static nominal + ADT)
High
Low
Goal: write type annotations as little as possible
Less code to write π
Compiler ensures consistency
IntelliSense helps with coding and reading
Method parameters and return value β
Variable declaration: var o = new { Name = "John" }
βοΈ
Lambda as argument: list.Find(i => i == 5)
βοΈ
Lambda declaration: var f3 = () => 1;
βοΈ in C# 10 (limited)
Array initialisation: var a = new[] { 1, 2 };
βοΈ
Generic classes:
constructor: new Tuple<int, string>(1, "a")
β
static helper class: Tuple.Create(1, "a")
βοΈ
Cβ― 9 target-typed expression StringBuilder sb = new();
βοΈ
Able to deduce the type of variables, expressions and functions in a program without any type annotation
Based on both the implementation and the usage
Example:
If something can be inferred as generic, it will be β Open to more cases π₯³
Pros:
code terser
automatic generalization
Cons:
we can break code in cascade
inference limited:
an object type cannot be determine by the call to one of its members (1) β exception: Record types π
sensible to the order of declaration (2)
(1) Example:
(2) Example:
The most questionable solution is to raise an exception π© (see )
π by Mark Seemann
method