When using apache commons csv (not very relevant),...
# getting-started
p
When using apache commons csv (not very relevant), how can I close the parser just after all rows are read from the sequence?
k
Copy code
return parser.use {
   it.asSequence()
   .drop(1)
   .map {...}
}
j
That probably wont work, as the file will be closed when the function returns, which is before the sequence is consumed. Its probably better to pass a lambda into the function that will be called for each item of the sequence (in this case, each line) Tbh, as this is "getting started", you could probably use a list, you would have some easier set of problems, unless your file is very very big.
💯 1
p
My file is very big, that's why I use sequence
In which chandel should i ask then?
j
So, easiest way is to pass a function into this one that does processing of the rows of data one at a time. Its hard to be specific as you dont say what you are doing with the data. For example, if its to put it in a user interface, you'll need to do something quite different than if its to calculate some totals or averages.
m
I think this is the right channel. Another option would be to use the
sequence
function. You would open and use the parser inside the lambda. Something like
Copy code
sequence {
    builder.parse.use { emitAll(it) }
}
Could make it an extension function on the builder class.
👍 1
h
You could also use a Flow, because it supports a callback, like closing your file, when the flow will be closed, if you already use coroutines.
w
Be careful with the sequence builder with resources. There's a foot gun here where the resources are not closed if you don't fully exhaust the underlying sequence with operators such as
.first()
. Flows don't have this footgun, and make resource handling a lot easier.
To clarify:
sequence { try { yield(1); yield(1) } finally { println("Finished") } }.first()
will not print "Finished" (Sorry, on phone)
😮 1
p
Good to know. So is it better to just choose flow over sequence "blindly"?
w
Not always, but if it wraps resources it simply becomes a lot easier to comprehend with flows
p
So, do sequences have a point over flow? I know, I know, apples vs oranges
w
In my personal opinion there aren't a lot of advantages aside from being in the standard library. But in a lot of people's minds Flows are reserved for much larger operations
p
But flows are not more heavyweight, right?
w
But flows are not more heavyweight, right?
Correct. I don't have numbers but from naive assumption the sequence builder is significantlt more expensive than the flow builder. In my humble opinion people associate
suspend
too strongly to something complex. Anyhow, I don't mean to hijack the thread.
p
Thank you. Just learning coroutines, and in the process of modernizing a heavy java project.
🔥 1
🍀 1
w
Oh yes, Java interop is definitely a disadvantage of Flows compared to Sequences
And of course, the annoyance of having to collect flows when you're not in suspending context
p
New / migrated parts will be In kotlin
k
By the way,
CSVParser.close
seems to just close the associated
reader
. So a workaround is to define the above function without closing (i.e. keep your function as it is in your initial post) and close the reader in the caller of your function. This is not generally applicable, but just for
CSVParser
.
m
I'm quite surprised that the
finally
doesn't get run. I would have assumed the second
yield
would throw a
CancellationException
. Good to know about that.