-
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
@BuilderInferencefor better generic type support. - Add
InvocationKind.EXACTLY_ONCEcontract 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.