Hello! I hope everyone is doing good. I've been wo...
# server
l
Hello! I hope everyone is doing good. I've been working for the last 2 years on Kotools Types, a Kotlin multiplatform library providing explicit types like
NotBlankString
or
NonZeroInt
that might interest you for: • ensuring that your data is valid through all your application • striving for totality by reducing the possible inputs or outputs • reducing runtime check to compile-time ones by using the compiler effectively. My client Smartch currently use this Open Source project for defining a precise domain in their backend applications. Like @flavio, I would like to get some feedback about what's good or bad in that project for improving it with our lovely Kotlin community. The JetBrains team also created a #kotools-types channel that you can join for discussing about this project. Thank you for your time and consideration! 🙏🏽
💡 1
🙌 6
f
This seems very interesting, and it's something I felt the need of in the past. Here are some thoughts: I can't seem to find the full documentation for this. Maybe the readme could include a fuller set of examples? Also it would be interesting to see some info on performance/memory overhead. Best of luck getting this out there!
🙏🏽 1
l
Thanks for your feedbacks @flavio! About the documentation, I'm still thinking about ways to add some examples to each public declarations available in the API reference. A possibility could be to add usage examples to all declarations directly in the API reference. I like this solution because it's simple and it improves the discoverability of declarations. It is also mainly inspired by the Arrow's API Docs (see their NonEmptyList type for example). Do you have any idea about this? Performance and memory overhead is a huge topic! We tend to mainly declare types as inline classes in this project for avoiding memory overhead, and types that are currently not declared as inline classes will be converted gradually (here's a migration example for the NotEmptyList type that will be available in Kotools Types 4.3.0). But what metrics are you interested in?
k
I had a quick look. I like the idea behind it; it reminds me of Ada's type system which is one of its main safety-related features. A couple of comments: 1. You use
Result
as return values. It's a matter of personal opinion, but I would have preferred throwing exceptions, to be consistent with what the Kotlin Standard Library does. 2. It would probably be beneficial for
NotBlankString
to implement
CharSequence
.
🙏🏽 1
l
Thank you @Klitos Kyriacou for your comments! 1. We will start migrating the builders returning a
Result
to new builders aligned with Kotlin standards in Kotools Types 4.3.0 (see the corresponding discussion on GitHub - I'm currently splitting related issues by type). This will be a lot of work to introduce these builders without breaking the existing API, but we will implement them incrementally. 2. The API of
NotBlankString
is currently incompatible with the
CharSequence
: the
NotBlankString.length
property returns a
StrictlyPositiveInt
instead of an
Int
. This choice was made for only providing an explicit API to these types. If a
CharSequence
is needed and you have a
NotBlankString
, you can convert it to a
String
, but this is an interesting point. What benefits you see for
NotBlankString
to implement the
CharSequence
interface?
k
Thanks, Loïc, the migration plan sounds good. I thought it might be useful to implement CharSequence as you can then pass it directly to functions that take that interface, but I understand why it's not possible, and the workaround is good.
l
@Klitos Kyriacou I see your point about implementing the
CharSequence
type. We may add more utilities for working with a
NotBlankString
like a
CharSequence
if users really need those. For now, we are just providing the
length
property, the
compareTo
and the
toString
functions (the
plus
operations for concatenating a
NotBlankString
are currently experimental). But if you need other utilities that could be added to the
NotBlankString
type, feel free to suggest it. Just another question about this topic: do you use often the
CharSequence
type? I usually use the
String
type for representing sequence of characters.
k
I don't remember any time that I deliberately used CharSequence, but sometimes I call functions on String that I thought were defined for String but in fact they're defined for CharSequence. For example,
"...".forEach {...}
and
"...".replace(regex, "...")
are both CharSequence (not String) extensions.
l
@Klitos Kyriacou That's true, a lot of declarations used on the
String
type are originally extensions for the
CharSequence
type. I just don't understand the advantages of the
CharSequence
abstraction. 🤔
c
I just don't understand the advantages of the
CharSequence
abstraction. 🤔
Performance is a big one. Creating and copying strings or substrings can be very expensive.
CharSequence
lets you use data directly from buffers such as
java.nio.CharBuffer
and
java.lang.StringBuilder
l
Thank you for participating in this discussion @Chris Miller. Do you have any use case in mind when is it better to use the
java.lang.StringBuilder
type instead of using the
kotlin.String
type?
c
One thing to note is, the usage of polymorphism forces boxing for value classes. For example,
NegativeInt
being an interface means all variables of that type must be boxed, even if it's always a
StrictlyNegativeInt
which is a value class.
l
That's correct @CLOVIS, using interfaces includes that underlying value classes will be boxed. In fact, I had a lot of design dilemmas on this topic. I didn't know what was the best solution between having an explicit hierarchy with interfaces and value classes at his bottom (for scalability), or declaring all types as value classes (for performance). I know that auto-boxing and unboxing heavily can lead to performance issues, but the current API uses the first approach for scalable declarations. Finally, as I'm thinking more about this library as a set of explicit types that could be used on any platform, I think that performance should be a priority. Do you have any advice or solution about this boxing topic?
c
There's no silver bullet. I participate in https://github.com/arrow-kt/arrow-exact which is a different way to do it, we only have value classes and no interface hierarchies.
l
@CLOVIS Interesting project!
@CLOVIS I feel like your point about boxing and interfaces is definitely something to document in the library.
1