> Another change is a set of new factory funct...
# announcements
e
Another change is a set of new factory functions for creating 
Duration
 instances from integer values. They are defined directly in the 
Duration
 type and replace the old extension properties of numeric types such as 
Int.seconds
.
I saw ☝️ in the release notes for 1.5 RC, and I'm curious what the reasoning is for deprecating the extension properties. I found it to be a very nice API. Was it about polluting the namespace?
👀 1
1
k
j
these new github unfurls are truly awful
😂 1
2
but yeah the extensions were great. now i have to copy/paste them to every project
n
heh
1
i
Extensions were great for constants, indeed, and not that great for numbers stored in variables. E.g. that's how converting java duration to kotlin duration looked like:
Copy code
fun java.time.Duration.toKotlinDuration(): Duration =
    this.seconds.seconds + this.nano.nanoseconds
It's quite strange that
seconds
is a property of
seconds
and
nanoseconds
is a property of
nano
numbers.
j
Instead of being deprecated, can be extracted to a standalone library? There are projects that "don't care" about Java. I think Kotlin should not take decisions based on Java, at least not like this.
i
This concern is not about Java, it's about how these extensions look when called on number variables.
j
Then are they being removed to work better with date libraries or similar libraries? I understand the use case, but I don't like because I think that
this.seconds.seconds
is something that will happen under the hood more the time and in utilities or extensions, but the rest of the time it works perfectly and there is where we are going to be the 99% of the time.
Why dont have both?
i
someSeconds.seconds
happens not under the hood, but every time you read
someSeconds
value from where it is stored as a number. As soon as you go from constants to variables, these extension properties begin to look as an abuse rather than a clever hack.
j
Yeah it seems like a long-term proposal for literal conversion notation would be a good path to pursue. I can do 2UL but not seconds.UL. So with some sigil to provide a factory extension or something we could enable literals to take on a new form (and maybe the functions could be marked const and be computed at compile-time producing constant dynamic bytecode for Java 11+)
1
e
I don't think I've ever thought about these extensions for variables where I wasn't already planning on using them, but that's just me.
i
We can consider returning these extensions in a more limited scope form, for example in a companion object or in another nested object in
Duration
together with a helper function for bringing this object into context, e.g.:
Copy code
fun duration(Duration.ConstructionExtensions.() -> Duration): Duration

val interval = duration { 1.minutes + 5.seconds }
1
e
I think I'd probably go with rolling my own or a 3rd party lib at that point 😬
Which I think I'm going to do (code and push to maven central coming shortly) 😄 https://github.com/eygraber/kotlin-duration-extensions
👍 2
Snapshot for jvm deployed. Other platforms and a mavenCentral release on the way
The artifacts are now live on mavenCentral. Enjoy!
i
Yeah it seems like a long-term proposal for literal conversion notation would be a good path to pursue.
@jw yeah, that also could be an interesting direction to explore. Any ideas how these custom literals could look like? I found one idea here: https://github.com/Kotlin/KEEP/pull/24#issuecomment-224888801, but it's not quite clear how to avoid conflicts with predefined literal suffixes.
j
Yep that's close to what I had in my head. JS also has tagged templates (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates) which basically serve a similar purpose.
j
I also miss these extensions 🙂 I agree they don't look great for anything other than literals, but I guess it's the dev's responsibility to use these extensions wisely. Using the factory functions for variables and the extensions for constants would be quite natural and convenient. The
duration { ... }
context could be an idea, but honestly I'm not sure the gain from the limited scope is worth the extra boilerplate. I like the idea of a sigil for literals, but I wonder how practical and understandable that would be (I also feel like that would be an unnecessary addition to the language).
j
How about reusing bound reference syntax on literals only but they would work like extensions?
4::seconds
,
"1234"::BigInteger
(that's a function call named like a type), Etc. And then it's basically a soft keyword on a regular extension function like Andrey proposed but they otherwise do not appear as extensions on the type.
🤔 1
And you could still have
1234::BigInteger
work with overloading
Probably too confusing with two semantics on a single syntax
2
Although it's close if you squint!
😄 1
j
Or, as @rnett mentioned we could define an annotation that limits an extension property/function so that it can only be called on literals of the corresponding type
r
There also is some of overlap with the collection and object literal discussions, it's effectively the scalar case of them (i.e. a tensor of
[1]
vs a tensor of
1
) so it would be nice to support it in a similar way to whatever ends up being done there. It's somewhat different semantics than the "unit conversions", but usually done via a similar syntax.
👍 1