Hi everyone, we'd like to know your opinion on ren...
# coroutines
i
Hi everyone, we'd like to know your opinion on renaming the
buildSequence
and
buildIterator
functions. Please share your thoughts regarding the names proposed in the attached post, especially if you find something confusing about any of them. Slack Conversation
t
I think
define*
makes the most sense semantically. Another good option might be
generate*
.
i
generateSequence
is already used for recurrent definition of a sequence:
generateSequence(initial) { e -> next(e) }
d
I prefer the define* over *from, because the "from" convention (in my experience/opinion) is typically used for non anonymous arguments (like a collection assigned to a variable name)
d
Maybe
yieldSequence
? it would clearly show the suspending nature of how the sequence is generated. Even though that differs from other builders out there, but that really is its distinguishing point, no?
i
@dave08
yield
is a suspend function that is used to output a value or several values to sequence (
yieldAll
). It would be very confusing to reuse it in a non-suspend context to name
yieldSequence
.
d
Well it's very obvious that it is not suspending from the function signature and IDEA gutter... it just shows that that's how the sequence is being built.
I see your point, but it's either to hide the implementation detail behind a name not related to coroutines, or to make it obvious...
b
Another option might be
sequenceOf
providing a population function. Then it would be easy to provide
iteratorOf
. You could even expand this to provide
mapOf { yield("a" to "b") }
and other variants 🤷
d
I'd say
defineSequence
is the least confusing.
d
From the choices stated, I guess the one I'd go for is
sequenceFrom
, it might be nice to also have
listFrom
, etc..., I just had a use case recently building a list out of optional function parameters... I had to do
buildSequence { param1?.let { yield(it) }; ... }.toList()
i
A case when
sequenceFrom
can be confusing is when the type parameter is specified explicitly:
Copy code
val empty = sequenceFrom<String> { }
val supertypes = sequenceFrom<Supertype> {
     yield(subtype1)
     yield(subtype2)
}
d
So then why not just
lazySequence { }
? Instead of using new terminology (
define
which seems to be the only possibility that won't overlap with existing functions, or cause these kind of confusions...), lazy is already used in kotlin for
by lazy { }
, wouldn't it be better? @ilya.gorbunov
😍 1
Then there could also be
lazyList { }
etc...
b
From my understanding it’s not lazy though. I think the builder function executes immediately, and just suspends once it has reached a
yield
. I have many
buildSequence
operations that does some expensive processing and then performs yield in a loop of output based on that processing. That being the case, I’d be surprised to find
lazySequence
blocking my current thread while the iterator gets the next value when I expected it not to happen until I try to consume it on a worker thread
i
@bdawg.io builder function starts executing only when the first element is queried from the sequence iterator.
d
Any chance
list { }
,
map { }
, etc... will also get in @ilya.gorbunov?
They also have
listOf
and
mapOf
...
i
For non lazy data structures we prefer to have
build
prefix, such as
buildString { }
. Though that is not set in stone yet, and can be discussed later. https://youtrack.jetbrains.com/issue/KT-15363
d
I mean lazy, using
yield
... since currently I've had a few use cases that I used
buildSequence { ... }.toList()
...
Oh, I see what you mean, since under the hood, such an implementation would use a mutableList anyways...
I guess it would really make sense with immutable collections...