I kinda think it's an awful idea to try to make ko...
# gradle
z
I kinda think it's an awful idea to try to make kotlin look like groovy. Many of Gradle's papercuts are because of ambiguous groovy syntax leading to unexpected code paths
8
☝️ 2
👍 11
👎 3
v
If they wouldn't try to to some degree, we probably wouldn't have type-safe accessors and soon assignment syntax, which both in absence make the Kotlin DSL much uglier to use and thus less poplar.
m
I think this is a documentation issue. Kotlin build scripts are not ugly without the
val foo by getting
and
String.invoke()
. The main problem is that a lot of the snippets are written for Groovy
I like
create("foo")
better than
val foo by creating {}
and Kotlin has its own syntax for DSL too. In theory it doesn't need to map the Groovy syntax
p
@mbonnin You forgot the
@Suppress("UNUSED")
before the latter statement 🧌
v
Which is just a work-around for an IDE bug again, because it is used to define the name. There is an open YouTrack issue about it afair
Kotlin build scripts are not ugly without the val foo by getting and String.invoke() .
Neither of them is what I mentioned. I said type safe accessors. The ones to get task providers and configure extensions
e
@Zac Sweers was your comment about property assignment syntax or collection literals?
z
Property assignment
e
I was going to disagree with you, but the more I think about it, the more I'm starting to agree. I really dislike
property.set(value)
though 🤔
j
This can improve how we can consume the plugins, but for me the real problem is finding a plugin which doesn't use lazy properties, and I doubt this improvement can change that as it is totally oriented to people with no experience in Gradle (which is, indeed, good tho). I am not sure if it would be possible to get rid of Provider/Property wrappers and still get lazy configurations by default. That should be the perfect solution... Maybe a special compiler plugin can do some magic by adding wrappers by default under the hood in both, scripts and any kt file which is in a module that applies
kotlin-dsl
or
kotlin("jvm")
+
java-gradle-plugin
I wouldn't say this is a patch, but as it is a feature it is going to be available for Gradle, it looks like a patch.
m
a special compiler plugin can do some magic by adding wrappers by default under the hood
That doesn't sound like going in the direction of sreamlining things 😅
I'm not even sure everything needs to be lazy. Take Android's minSdk, I'm fine with it being a
var
. It's not like I will run a huge computation to get it
j
I don't know if it is possible to get a lazy configuration in a world without any compiler plugin by replacing
val foo: Provider<Foo>
with
val foo: Foo
and
val foo: Property<Foo>
with
var foo: Foo
. But if it was possible, that would be the right direction for sure
m
The less compiler plugins, the better for me. Actually, I'd be fine with custom assignment if it were in the Kotlin language too but having
Gradle Kotlin != Other Kotlin
is the main pain as far as I'm concerned.
b
I never understood what the issue was with the original syntax or why they would need a compiler plugin to support this. What's wrong with using
var foo = Foo
with a custom setter that acts like a lazy property configuration, e.g.,
set(value) { lazyConfig(*field*) }
? Why was
setFoo(...)
ever necessary in the first place?
I would like to argue that having two different syntaxes for Gradle is highly suboptimal for search and documentation and the more syntax the two DSLs can share, the better. Especially if Kotlin already supports the original syntax, why change the syntax just to be different? This avoids having to migrate a million different build scripts when switching from Groovy to Kotlin, and lets existing Groovy developers use the syntax they are already familiar with...
z
I would counter-argue that it's totally normal and ok for different programming languages to have different syntax.
j
@breandan because without a different syntax you can't get lazy configuration
b
Programming languages? Maybe. Build systems? I'm not so sure. Plenty, perhaps even the majority of people who use Gradle are only vaguely familiar with Groovy/Kotlin and just want their build script to work. https://www.jetbrains.com/lp/devecosystem-2022/java/#which-build-systems-do-you-regularly-use-if-any-
Lazy configuration wouldn't work with property delegates?
j
At least in the current state, so you are forced to use
foo.set(...)
, indeed you are still doing that, but with the compiler plugin, under the hood. Anyone know if there are public docs about if it was possible to create a design without wrappers and it was discarded?
More context here: https://github.com/gradle/gradle/issues/9268 I think delegates was proposed in a comment, but they are not on the OP.
An additional problem, this improves the syntax to set a value, but you still doesn't get the same when you want to get the value:
Copy code
val foo: Provider<Int> = provider { bar.get() + baz.get() } // works
val foo: Provider<Int> = provider { bar + baz } // doesn't work
v
Which is a good thing. If that worked, you would all too easily make the property eager suddenly accidentally. Which probably also is the important point against delegates. If you want the value to be eagerly get, it should be explicit and the user should think about whether there might be a way to properly use the value lazily instead.
Copy code
val foo = bar.zip(baz) { x, y -> x + y }
c
@mbonnin sorry I'm late but about https://kotlinlang.slack.com/archives/C19FD9681/p1679407685080749?thread_ts=1679375245.749489&amp;cid=C19FD9681 Imagine you have a convention plugin, and you have a task that will use that value as an input. What do you do? If you assign it directly it would be empty (or have the default value. You can use afterEvaluate to adding the value from the android extension...
Currently the solution is usually something like
myTask.minSdk.set( provider { androidExtention.minSdk })
But it can become messier, or you may keep a reference to something you shouldn't and then Configuration Cache doesn't work...
While, making minSdk lazy (a Property) allows you to connect the 2 properties/providers and be sure you'll have the right value when you need it
m
@cristiangm fair enough. That doesn't change the initial point about Kotlin not needing to look like Groovy though
c
yeah, nothing to say about that. For me
.set
or
=
seems controversial enough, and kind of subjective or a matter of taste (basically I don't want to have an opinion 😛 )