"toUByte" - can't 'thar from 'ere

I’m doing some image manipulation stuff, and UBytes are great, thank you!
I have to do some math on them, and noticed that “toUByte” doesn’t seem like a first-class citizen. For example, if I do some math, end up with a double, I have to first .toUInt() or .toInt() before I can toUByte().

Why is .toUInt more cool than .toUByte? Just an oversight?

FR: All the toUnsigned converters exist in all the same places that their toSigned siblings exist.

Two reasons:

  1. Conversion between floats and bytes are first-level citizen in the platform. Meaning Kotlin does not do it itself, but delegates to JVM. This way, it is a general contract for any Number to be able to cast to Byte. UByte is not a Number yet. Which leads to second point.

  2. Unsigned numbers are still in experimental phase, so library developers probably do not want them to be fully and seamlessly integrated in the code yet, because there could be problems later.

Ok. But still a FR because

A. I’m happiest when I’m insulated from the underlying stuff.

B. If the mental contract for “Number” is “can get to another Number type via toOther()” and then it isn’t there, it is not “least surprised.”

And I just ran into UByte not being serializable. (unlike other Number friends)

We have a small lib, started before kotlin experimental unsigned support where the unsigned do extend Number (but serialization is not yet there)

Maybe it could be useful for you

I’ve temporarily given up on Unsigned. Extra conversion steps, different supporting functions and not serializable outweighed the space and speed advantages (in my particular case).

Perhaps we have not envisioned the use cases where Double.toUByte() can be useful. Could you describe your in more detail?

Same places that Double.toByte() are useful.
myUByte = (myUByte.toDouble() * myPercentDoubleForChannelFiltering).toUByte()
(I’m masking a luminance channel of UBytes/pixels by multiplying by a 0.0…1.0 percent)

It seems like a rather rare use case. Why not introduce your own extension for that?

Totally can do that. The reason for this thread was for me to get a better understanding of the “expected contracts” that Kotlin provides.

For example,

  • Q: “Does every Number have toOtherNumberType()?” A: nope, Unsigned is special. But maybe someday.
  • Q: “Should I expect toUByte() every place there is toByte()?” A: not always. But I should be able to bounce through toByte().toUByte() in those cases.
  • Q: “Cool. What is the pattern?” A: (I’m not sure yet)

I ran into similar things when I was asking about functions like “chunked()” that were available to Lists but not Arrays. It is fine if the answer is “not many people have mentioned it, so don’t worry about it.”