Kotlin quicky: Under the hood of collecting flows in Android with Kotlin
Tags: android, kotlin, mobile, tristan
Published: 2022-11-22 07:40:53

### Introduction
- Anytime I find something interesting about Kotlin I will post it here.

### Resources
- [Main source](https://elizarov.medium.com/simple-design-of-kotlin-flow-4725e7398c4c). I would really recommend reading this before continuing.

- Originally I wanted this to be a quick little tutorial about how we can collect from flows, but a lot goes on under the hood with flows and I am not sure if I fully understand but this is my best shot. If anyone has anything to add please comment below.


###Flows
- So before we start collection from a flow lets first create on:
```
override suspend fun testFunc()= flow {
        emit("LOADING")
        try {
            emit("SUCCESS")
        }catch (e:Exception){  
            emit("FAIL")
        }
    }

```
- The code block above basically leaves us with 2 questions:

**1) what is the trailing lambda in flow doing ?**
**2) where the heck is emit() coming from?**

#### 1) what is the trailing lambda in flow doing ?
- If you are unfamiliar with the term `trailing lambda`, check out the documentation, [HERE](https://kotlinlang.org/docs/lambdas.html#passing-trailing-lambdas).
- Now lets move on and look at the documentation for [flow{}](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/flow.html) we can see it takes a very unusual parameter, `block: suspend FlowCollector<T>.() -> Unit`. Generally this syntax is called a `function type`, which allows us to define the signature of the high order function. What's interesting is the `.() -> Unit`, this makes it a function type with a `receiver`. 

- A receiver is defined in the documentation as:
 `Function types can optionally have an additional receiver type, which is specified before the dot in the notation: the type A.(B) -> C represents functions that can be called on a receiver object A with a parameter B and return a value C`

- But doesn't calling `FlowCollector<T>.() -> Unit` seem a little odd? We are calling a function on FlowCollection that has no parameters and returns nothing. It is odd until we learn about [Type Safe Builders](https://kotlinlang.org/docs/type-safe-builders.html). `.() -> Unit` is used to create a type safe builder

#### Type safe builders
- [Type Safe Builders](https://kotlinlang.org/docs/type-safe-builders.html)  make all the magic disappear. When we put:
```
flow{   }

```
- It is really a function call that takes a lambda expression as an argument, which is:
```
public fun <T> flow(  
  block: suspend FlowCollector<T>.() → Unit
): Flow<T>
```
- It takes one parameter called `block`, which itself is a suspending function. With the type of the function being, `FlowCollector<T>.() → Unit`, which is `function type with a receiver`. Meaning, we need to pass an instance of type FlowController (the receiver)to the function(flow), which allows us to call members of that instance inside the function. Meaning `flow{}` gets handed an instance of FlowController and inside of flow we can call the FlowController's emit() method. But where is the instance of the FlowController coming from? The [collect()](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html) method!

#### collect()
- So an instance of FlowCollector is coming from [collect()](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/collect.html), how?. Well mainly because it says so in the blog post, [HERE](https://elizarov.medium.com/simple-design-of-kotlin-flow-4725e7398c4c#1ce6) but we can do a little digging. Now `collect()` takes a collector of type FlowCollector and emits values to it. The normal call looks something like this:
```
myFlow.collect { value -> println("Collected $value") }

```

- The trailing lambda might look normal but its actually not. FlowCollector is considered a `functional SAM(single abstract method) interface`. With a functional SAM interface Kotlin allows us to do a `SAM conversion`, which makes our code more precise. So the lambda here:
```
collect { value -> println("Collected $value") }
```
- Is actually instantiating the FlowCollector interface and implementing the `emit()` method. `value -> println("Collected $value")` is actually us implementing the emit() method. Which is then passed to the `flow{}` builder.

### Still confused?
- Me too but we can make things a little better if we remove SAM conversion all together and get an implementation of the FlowController like this:
```
val data = object : FlowCollector<YourReturnDataType>{
    override suspend fun emit(value: YourReturnDataType) {
         println("Collected $value")
    }

```
- Which we could then pass to collect like this:
```
myFlow.collect(data)
```
- Again, still a little confusing but this does make it a little more clear that we are passing a value to the collect method. this value just happens to be an instance of FlowCollector and is used by flow{}

###Conclusion
- Thank you for taking the time out of your day to read this blog post of mine. If you have any questions or concerns please comment below or reach out to me on [Twitter](https://twitter.com/AndroidTristan).