Elizarov answered that channels are async, im tryi...
# coroutines
d
Elizarov answered that channels are async, im trying to approach from the sequence end to understand if they are not async, how are they different from regular kotlin sequences?
v
They are the same. Seriously
In other words, a sequence is a state machine. You ask for an element, and it gives you a value depending on its state. Kotlin coroutines is a general way to build such state machines, and in its simplest form they can be sequences.
d
So why did they bother making it part of coroutine core?
v
Because why not, literally 🙂
d
Oh 😲
v
I agree that
buildSequence
is kinda a side use of Coroutines, but it is nice to have, especially since K is trying to compete withy Python
d
Isnt a regular sequence enough to compete?
Thanks for clearing me up on this, I thought I was getting things wrong... 😄
g
@voddan I dont know If I would be as fatalistic as that, the coroutine implementation embeds what is often a huge part of the state machine dispatching logic for you. simply-put, the old school
generateSequence
will often require a
when
statement where
buildSequence
doesn't. I've used this for test-data where I want lazy creation of elements (IE, I cant simply enumerate them eagerly), consider:
Copy code
val resources = buildSequence {
  yield(makeExpensiveResourceOne())
  yield(makeExpensiveResourceTwo())
}
with generate sequence
Copy code
//no good, its eager
val resources = listOf(makeResourceOne(), makeResourceTwo()).toSeq()


val resources = (1 .. 2).toSeq().map {
  when(it) {
    1 -> makeExpensiveResourceOne()
    2 -> makeExpensiveResourceTwo()
  }
}
d
@groostav Nice, but one could always do:
Copy code
val resources = listOf(::makeExpensiveResourceOne,::makeExpensiveResourceTwo).toSeq().map { it() }
g
this is true
and its true generally @dave08
you will almost always find functional ways to achieve things that you could probably express a little bit more traditionally/emperically with coroutines
My personal favourite place for coroutines (and in a place where i have zero experience with them) is with the Unity game engine where you cao do things like
Copy code
async void doAnimation(){
  characterModel.displayedFrame = hitFrame[0]
  characterModel.location -= 5
  nextFrame() //suspending function

  characterModel.displaedFrame = hitFrame[1]
  characterModel.location -= 2
  nextFrame()
}
d
I think i figured a use case for coroutine sequences over regular ones: when the generation process is more involved
buildSequence
is better than regular Kotlin sequence generators, like with yield on conditions and yieldall that can produce many next values in one shot that can be iterated through one by one. Whereas regular sequences can generate only the next value from an isolated computation or as an accumulation of a previous result apon iterating through each value So for concurrency there are no advantages over sequences, but there are more options on how to actually generate them.