-
Notifications
You must be signed in to change notification settings - Fork 75
.toDataFrame
fixes
#1475
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?
.toDataFrame
fixes
#1475
Conversation
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.
Great, this logic is now really clear!
But please add a KDoc - or at least a comment for now, - to clearly define the behavior of toDataFrame
; it's not actually trivial.
val childCol = df[Entry::child] | ||
childCol.kind() shouldBe ColumnKind.Group | ||
childCol.asColumnGroup().columnsCount() shouldBe 0 | ||
childCol.kind() shouldBe ColumnKind.Value |
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.
Oh, that was weird, didn't know!
I have to disagree. Adding val myFunction: (String) -> Unit = { arg1 ->
doSomething()
}
fun myFunction(arg1: String) {
doSomething()
} It increases cognitive load. I'd be fine if they were all single-line-returns too, but we're a JetBrains Kotlin library, so if we don't follow the guidelines, then who does? :P But I understand it can be annoying if it fails the build :) For that I can recommend installing the KtLint plugin in the IDE and binding it to the reformatter, Ctrl+Alt+L. It highlights these cases and can fix them with one push of a button, or even upon file-save. Personally, I use it with pleasure, and as a result, the ktLintCheck almost never complains even though I often forget commas, write too long lines etc. And yes, sometimes it's a bit of a back-and-forth between me and the linter, but in the end the code looks clean, consistent, and readable. |
I agree with the following
However in Kotlin anything can be a single expression:
Key point why i'd like that function to have a body: a lot of lines of code in the expression. We can keep this rule but split expressions into multiple statements, and technically linter won't complain |
properties { | ||
preserve(DataFrame::class) // this@properties: TraversePropertiesDsl - always works | ||
} | ||
preserve(B::row) // this@toDataFrame: TraversePropertiesDsl - doesn't |
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.
can we deprecate this function here? since it doesn't always work
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 increase in robustness :)
ktlint_ignore_back_ticked_identifier = true | ||
ktlint_standard_multiline-expression-wrapping = disabled | ||
ktlint_standard_when-entry-bracing = disabled | ||
ktlint_standard_function-expression-body = disabled |
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.
Turning this off project-wide disables the quick-fix too. I use this quite often :( I'd rather recommend suppressing it on a class/file/function basis if you really need it for clarity. The KtLint plugin has a quick-fix option for suppressing.
|
||
private fun KType.classifierOrAny(): KClass<*> = classifier as? KClass<*> ?: Any::class | ||
|
||
private fun KClass<*>.properties(): List<KCallable<*>> { |
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'd either rewrite it declaratively/functionally, like:
private fun KClass<*>.properties(): List<KCallable<*>> =
memberProperties
.filter { it.visibility == KVisibility.PUBLIC }
// fall back to getter functions for pojo-like classes if no member properties were found
.ifEmpty {
memberFunctions
.filter { it.visibility == KVisibility.PUBLIC && it.isGetterLike() }
}
or imperatively:
private fun KClass<*>.properties(): List<KCallable<*>> {
val publicMembers = memberProperties.filter { it.visibility == KVisibility.PUBLIC }
return if (publicMembers.isEmpty()) {
// fall back to getter functions for pojo-like classes if no member properties were found
memberFunctions.filter { it.visibility == KVisibility.PUBLIC && it.isGetterLike() }
} else {
publicMembers
}
}
(or a variant of either). In either case the linter won't complain while sticking to one code paradigm.
@Interpretable("toDataFrameDsl") | ||
public inline fun <reified T> Iterable<T>.toDataFrame(noinline body: CreateDataFrameDsl<T>.() -> Unit): DataFrame<T> = | ||
createDataFrameImpl(T::class, body) | ||
createDataFrameImpl(typeOf<T>(), body) |
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.
nice! We should really do a sweep of ::class
usage in DF. typeOf<T>()
is cheaper I believe
class TestItem(val name: String, val containingDeclaration: MyEmptyDeclaration, val test: Int) | ||
|
||
@Test | ||
fun `preserve empty interface consistency`() { |
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.
does it work as well for interfaces, data classes, and objects?
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.
No for data classes - they require at least one property. But in general anything T that has no member properties / getter like functions, here we rely on Kotlin reflection
Fixes #1465
Btw i think strict
ktlint_standard_function-expression-body
rule is unnecessary, functions with return and with expression body can be a preference and coexist. At least for me this rule ALWAYS fails and forces me to rewrite