having trouble converting a small bit of java to k...
# announcements
s
having trouble converting a small bit of java to kotlin.
Copy code
for (Map<String, String> serviceOutputs; (serviceOutputs = resultReader.read(header)) != null; ) {
    try {
        final double elapsed = Double.parseDouble(serviceOutputs.get("__elapsed"));
gets converted to
Copy code
var serviceOutputs: Map<String, String>
while (resultReader.read(*header).also { serviceOutputs = it } != null) {
  try {
    val elapsed = it["__elapsed"]!!.toDouble()
which doesn’t work because
it
can be null, and
serviceOutputs
can’t be null. I can correct this to:
Copy code
var serviceOutputs: Map<String, String>?
while (resultReader.read(*header).also { serviceOutputs = it } != null) {
    serviceOutputs?.let {
      try {
        val elapsed = it["__elapsed"]!!.toDouble()
but that is pretty messy and not indicative at all of what is happening.
serviceOutputs
can never be null in the block, and using a
let
is messy. Any way to accomplish this a bit cleaner?
1
n
I guess you actually need the value of serviceOutputs after the while loop ends?
Because, it does not serve any other purpose that I can see, does it?
Actually, serviceOutputs will always be null when the loop exits. so why have it as a variable at all?
s
ah yeah that was automatic conversion. it’s such a large method I wasn’t looking through to see what was actually happening. EOD and I wasn’t thinking.
let me refactor that out and just use a loop with
it
and see what I get.
n
I guess it's still a bit tricky because you can't declare the variable in a while loop itself
n
Copy code
while (true) {
	val serviceOutputs = resultReader.read(header) ?: break
	val elapsed = serviceOutputs["__elapsed"]?.toDouble() ?: error("No __elapsed field")
n
yeah, that's where i was going next
s
that’s a good solution.
n
while (true) doesn't usually make me feel great but it's pretty practical 🙂
n
I find myself doing
while (true)
kinda surprisingly often
n
nicest is probably honestly to factor out this pattern
it's a very obvious pattern. python actually provides a special construct, that lets you transform something like this from a while loop to a for loop
ohhhhh
I know
n
you could probably make some kind of
resultReader.readToSequence(header).forEach {
s
yeah I was playing with a foreach, wasn’t having any luck.
n
this already exists i think generateSequence
Copy code
generateSequence { resultReader.read(*header) }.forEach { ... }
Or even:
Copy code
for (x in generateSequence { resultReader.read(*header) } ) { ... }
s
both of those seem good. As long as I can avoid a bunch of elvis operators, since I don’t care about the null case anyway I think it’ll be good. Let me play around with both of those.
n
yeah i mean those two its just th eusual for loop vs for each trade-off, pretty orthogonal to everything else
important thing is to get the sequence that we want
s
yeah, eventually I’m trying to migrate this to a bunch of coroutines, just trying to make sure I don’t break anything in the interim. thanks for all the help you two!
n
well, using a
sequence
is basically a coroutine, in a sense 🙂 Sure, np!