-
Notifications
You must be signed in to change notification settings - Fork 64
Add persistent Collection builder functions #166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
fe58e7d
to
bc52615
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation for the functions should be amended. Otherwise, LGTM.
bc52615
to
20ad7a1
Compare
* The list passed as a receiver to the [builderAction] is valid only inside that function. | ||
* Using it outside the function produces an unspecified behavior. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Builders in kotlinx.collections.immutable are capable of constructing a new persistent collection multiple times. However, I'm struggling to identify a compelling use case for retaining a reference to the builder and utilizing it outside the builderAction. If we constraint the builder to be valid only within the function, could using a MutableList
as the receiver be a more performance-efficient choice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @ilya-g, WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like if that were the case, mutate
would already be optimizing this in the same way, no?
62dfb51
to
c90d590
Compare
c90d590
to
1ac235e
Compare
core/commonMain/src/extensions.kt
Outdated
@OptIn(ExperimentalTypeInference::class, ExperimentalContracts::class) | ||
public inline fun <T> buildPersistentList(@BuilderInference builderAction: PersistentList.Builder<T>.() -> Unit): PersistentList<T> { | ||
contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) } | ||
return persistentListOf<T>().builder().apply(builderAction).build() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Annotate
@BuilderInference
for better generic type support. - Add
InvocationKind.EXACTLY_ONCE
contract to indicate the function parameter will be invoked exactly one time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK @BuilderInference
is a no-op, and has been for a while now. My understanding is that builder inference is applied by default everywhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't remove it to keep the same behaviors as the builders in stdlib.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The opt-in for ExperimentalTypeInference::class
is unnecessary now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
1ac235e
to
f4b5f15
Compare
core/commonMain/src/extensions.kt
Outdated
@OptIn(ExperimentalTypeInference::class, ExperimentalContracts::class) | ||
public inline fun <T> buildPersistentList(@BuilderInference builderAction: PersistentList.Builder<T>.() -> Unit): PersistentList<T> { | ||
contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) } | ||
return persistentListOf<T>().builder().apply(builderAction).build() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use mutate
instead. Same for the other builder functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Replaced.
c2ade34
to
505c5c2
Compare
It looks like you lost the |
Oooo, looks like |
505c5c2
to
d0eac5a
Compare
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
} |
Yes, but contracts currently aren't inferred nor inherited automatically like this, so sadly you have to explicitly add the contract to |
I believe we should add contracts in a separate PR. |
d0eac5a
to
16df77e
Compare
Closes #137.