Why isn’t it allowed to pass the constant `0` to a...
# announcements
m
Why isn’t it allowed to pass the constant
``0``
to a
``Double``
? Why
``0.0``
?
p
Because 0 is an int and not a double?
z
Unlike Java, kotlin doesn't convert number literals for you. This gives some of the reasoning.
m
@Paul Woitaschek no, it’s a number literal with no type. It only becomes an
``Int``
when inferring a type. @Zach Klippenstein (he/him) [MOD] actually Kotlin does.
p
Uh now that's interesting!
Where can I read up on this?
m
I don’t know but the link that @Zach Klippenstein (he/him) [MOD] mentioned is a good starting point. It’s actually mentioned there but for some reason it’s not available for floating point. See comment of first line.
👍 1
It would be great to have
``0``
as universal unitless value. In
``kotlin-css``
for example we could just write
``top = 0``
``top = 0.px``
. But that’s another more advanced use case 😄
r
universal unitless value
So,
``null``
m
No,
``null``
is absence of value.
``0``
means
``0``
. Whether the
``div``
is
``0``
``cm``
,
``px``
or
``rem``
away from the top doesn’t matter - it’s at the top. Hence it’s just
``0``
in CSS.
``null``
would mean that the distance to top is not defined.
r
I don't think there is a such thing as a universal unitless
``0``
. What
``0``
means is dependent on the unit. Usually systems line up their
``0``
values, but not always. For example,
``0C != 0F``
.
That may sound pedantic, but that is what universal means.
``0``
is used for a lot more than just CSS size definitions.
m
Once it has a type then yes. But a unitless
``0``
can be converted in any type that supports it. Just like we have in Kotlin already:
Copy code
``````val int: Int = 0
val long: Long = 0 // implies 0L

if (int == long) // not allowed``````
The same way I could write
Copy code
``marginTop(0)``
And allow that only for integer
``0``
and no other. The respective overload would resolve that properly and it only works if explicitly supported.
r
But, in your first example,
``top = 0``
still wouldn't work as
``top``
isn't a number.
And having a concept of letting types state whether they have support for the magic
``0``
sounds like it would cause far more problems than solve.
m
Yeah that’s why I don’t like
``kotlin-css``
and have written my own library. Properties are too inflexible, functions are much better here.
``Zero``
could work the same way as
``Nothing?``
does. It only has one valid value. Only difference is that it is inferred as
``Int``
and
``Zero``
is only used explicitly.
r
But how would that work for other types? For example,
``top = Zero``
. How would you be able to automatically convert
``Zero``
to a
``LinearDimension``
? That could get more complicated with, say, transforms. Should
``Zero``
mean
``Identity``
or a matrix full of `0`s?
m
I wouldn’t add a conversion feature unless Kotlin gets one in general. Thus I’d only support it for parameter overloads, just like
``Nothing?``
.
``top(0)``
With
Copy code
``````fun top(value: Zero) {
top(LinearDimension("0")) // example
}
fun top(value: LinearDimension) { … }``````
``0``
is not a matrix and thus wouldn’t be an acceptable value. In that case you’d probably use
``Matrix.identity``
or alike.
r
That still seems like it would cause more problems than it solves to me, but I may just not be seeing the whole picture. That would also be a breaking change. For example, the following would fail:
Copy code
``````var x = 0
x = 5  // Error: Expected Zero, found Int``````
m
That’s why it should be explicit.
``vax x = 0``
//
``Int``
``vax x: Zero = 0``
//
``Zero``
Just like
``var x = 0``
//
``Int``
``var x: Long = 0``
//
``Long``
It doesn’t even have to be a real type. It could just be valid for overload resolution and parameters with that value are actually
``Int``
on the callee side - or totally inaccessible.
r
But
``0``
wouldn't be an
``Int``
, it would be a
``Zero``
. Adding special implicit cases like that is exactly the "magic" that Kotlin tries to avoid.
m
``0``
on its own has no type. Otherwise you couldn’t assign it to
``Byte``
,
``Long``
, etc.
Another path would be similar to what Swift does.
Copy code
``````class LinearDimension(val value: String) {
companion object: ZeroConstructible {
override fun constructFromZero() = LinearDimension("0")
}
}

val foo: LinearDimension = 0``````
It’s an API that specifies how types can be constructed from literals. It’s not type coercing.
r
Hmm, I've never seen that before (I don't use Swift). Are there such constructs for any kind of literal, or is
``0``
special?
m
They don’t have it for
``0``
specifically. They have for
``IntegerLiteral``
,
``FloatLiteral``
,
``StringLiteral``
,
``ListLiteral``
(e.g. for Set construction) etc.
+
``MapLiteral``
Actually it’s called
``ExpressibleBy…``
by now https://developer.apple.com/documentation/swift/expressiblebyintegerliteral
r
In that case, you could achieve the same functionality (and more) by simply allowing setters of multiple types. For example
Copy code
``````var x: LinearDiminsion by ...
set(value) { ... }
set(value: Int) { set(value.px) }``````
m
That’s a potential explosion of overloads though
``Zero``
would be already but still an acceptable trade-off for simpler CSS API.
That would be incorrect
You can have unitless
``0``
but not unitless
``1``
in CSS.
r
Sure, but this would need to apply universally to Kotlin, not just CSS.
m
``1``
needs a unit and cannot be implicitly pixel.
Actually there are cases in CSS where you must remove the unit from
``0``
. For example in some
``calc(…)``
expressions. So
``0``
should never implicitly become
``0px``
.
r
That sounds like a problem with CSS, not an example of something Kotlin should try to emulate. 🙂
m
Why not? We could use
``0``
everywhere where it has the same meaning.
``Int``
,
``Byte``
,
``Long``
,
``Double``
and customs like
``css.LinearDimension``
.
We’re mixing up two things though. My initial question was about
``0``
for
``Float``
and
``Double``
😄
r
Indeed, but I was intentionally not discussing number literals. I'm talking about the magic
``0``
. That's where I came into the conversation (and prefixed my original comment accordingly to make that clear).
m
``css.LinearDimension``
``0``
not the
``Int``
value
``0``
r
I don't really have anything to add on whether
``0``
should be a valid
``Double``
. I'm just adding my \$0.02 on whether
``0``
should be a special unitless universal, and what that would entail.
m
It would be more like a special case of integer literal that can be specifically addressed.
A zero literal
r
Indeed. I'm still not convinced (yet?) that it's a good idea, but it's definitely given me something to thing about. Thanks for humoring me.
m
That’s okay. Doesn’t need to be solved by now :) It’s a topic for another day. And also more in the DSL space where it would be quite useful. Maybe in Math too, I don’t know. Back to using
``0``
literal for floating-point values.
👍 1
z
yall might be interested in the #language-proposals and #language-evolution channels if you’re not already in them