F# For Dummys - Day 8 Function && Pipeline
Tags: fsharp
Published: 2024-05-20 11:11:06

Today we learn how to define a function and pipeline
#### what is function
function is a block of code that takes input values (parameters), and returns an output value</br>
normally we perform some task with the input, it will be less useful just return the input value</br>
- funtion no param input:
```f#
let say_hello() = "Hello"
printfn "say_hello: %s" (say_hello())
```
- funtion one param input
```f#
let say_hello_to name = "Hello " + name
printfn "say_hello_to: %s" (say_hello_to "Lucy")
```
- funtion two param input
```f#
let say_hello_to name0 name1 = name0 + " say Hello to " + name1
printfn "say_hello_to: %s" (say_hello_to "Lucy" "Lily")
```
- function can be a param of other function
```f#
let applyTwice f x = f (f x)
let increment x = x + 1
let result = applyTwice increment 5

printfn "Result: %d" result
```
increment is the first param of function applyTwice here, it's increment(increment(x)), result is (5 + 1) + 1 = 7
#### lambda
lambda expression is an anonymous function (a function without a name) that you can define in place, often to be passed as an argument to higher-order functions
syntax of a lambda expression
```
fun arguments -> expression
```
a simple add function
```f#
let add x y = 
    x + y
printfn "%d" (add 3 5)  // Output: 8
```
a lambda version
```f#
printfn "%d" ((fun x y -> x + y) 3 5)  // Output: 8
```
you can not use this fun at other place as it *Dispose* after finish
#### pipeline

- 
forward pipeline |>, data flow from left to right

we can combine multiple functions one after one</br>
function1 |> function2 |> function3, it's called pipeline
the function param example could be like this:
```f#
let applyTwice f x = f x |> f
let increment x = x + 1
let result = applyTwice increment 5

printfn "Result: %d" result
```
another longer pipeline
```f#
let addOne x = x + 1
let square x = x * x
let subtractFive x = x - 5

let result = 5 |> addOne |> square |> subtractFive // (5 + 1)^2 - 5
printfn "The result is %d" result // output: The result is 31
```
the output of first function is the input of next function</br>
result = 5 |> addOne, addOne get 5, return 5 + 1 = 6, square get 6, return 6 * 6 = 36, substractFive get 36, return 36 -5 = 31

- 
<| backward pipeline, data flow from right to left</br>
```f#
let addOne x = x + 1
let square x = x * x
let subtractFive x = x - 5

let result = subtractFive <| (square <| (addOne 5))
printfn "The result is %d" result // output: The result is 31
```
#### why pipeline
an example for morning routine
```f#
let getOutOfBed () = "Out of bed"
let brushTeeth state = state + " -> Brushed teeth"
let takeShower state = state + " -> Took shower"
let getDressed state = state + " -> Got dressed"
let eatBreakfast state = state + " -> Ate breakfast"

let morningRoutine =
    getOutOfBed ()
    |> brushTeeth
    |> takeShower
    |> getDressed
    |> eatBreakfast

printfn "Morning routine completed: %s" morningRoutine // output: Morning routine completed: Out of bed -> Brushed teeth -> Took shower -> Got dressed -> Ate breakfast
```
there is an equivalent way to get the same result, which is nested function calls
```f#
let getOutOfBed () = "Out of bed"
let brushTeeth state = state + " -> Brushed teeth"
let takeShower state = state + " -> Took shower"
let getDressed state = state + " -> Got dressed"
let eatBreakfast state = state + " -> Ate breakfast"

let morningRoutine = eatBreakfast(getDressed(takeShower(brushTeeth(getOutOfBed()))))
printfn "Morning routine completed: %s" morningRoutine
```
the last function **eatBreakfast** is put in the first place</br>
which way do you prefer</br>
we can see the pipeline way is more readable in this style:
-   The order of operations is written in a natural, top-to-bottom manner, which is easier to read and understand
-   It is more intuitive because it reads like a sequence of steps or instructions
-   Adding or removing steps is straightforward, you just add or remove lines
-   Each function operates on the result of the previous function, clearly showing the flow of data

pipeline way is recommended in F#, the data flows in pipeline, elegant!