Refinement Types: Design Notes #455
Replies: 3 comments 5 replies
-
I can definitely think of some scenarios where this would be a cool feature! For instance, having the type system know about non-empty collections would be great. Here are a few thoughts that jump to mind after reading the design notes. I haven't ever used a language that has refinement types like this (the closest I've gotten is TypeScript), so I'm no expert, and these might be things that have been solved (or rejected) by other languages 😁:
Anyway, that's the end of my rambling. Thanks for sharing the design notes! It's really interesting to see the thought process even for a feature that's not going to be implemented. |
Beta Was this translation helpful? Give feedback.
-
Edit: This got a little rambly, so apologies if it's difficult to read! I think subtypes would be the way to go if this feature ever happens. opaque typealias Foo = Bar
typealias Baz = Bar satisfies { it.foo() } No magic compiler detection, instead all just contracts driven. opaque typealiases don't have
I really don't think that's as big of an issue as you think. This is already necessary with I think having extensions take priority over members for refinement subtypes makes perfect sense, and helps address that typetag feature like you said. I really don't like Implicit Refinement. It's too much implicit behaviour for Kotlin. Instead, I think type casts are reasonable in such a case. w.r.t. refinements that refer to a member property, I think contracts and smart casts should be extended first to support that, and then it'll work naturally for refinements too.
This is just intersection types I think. Simply any type that happens to have
Smartcasts already deal with this. Use the same system (and make them smarter as well by allowing a way to declare that a |
Beta Was this translation helpful? Give feedback.
-
It may be worth noting prior art here in the form of Java's validation libraries: fun foo(@Email email: String) { ... } Frameworks like Spring or Micronaut can enforce these constraints at runtime, but not always. It depends if the method is being invoked by the framework or not. I would prefer Kotlin continue its tradition of leaning into existing Java practice both for its familiarity and the practical benefits e.g. none of the refinement type proposals given above address reflection or database validation at all, whereas validation annotations do. So one practical compromise might be to look at what it'd take to improve the validator libraries. For example, off the top of my head:
I guess you can think of many more. Data validation is useful but there's a lot of prior art here already that's deeply integrated with infrastructure like web servers and ORMs. Static analysis is great but there's no need to let perfect be the enemy of the good here. Even just more consistent and usable runtime validation would be an upgrade. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This is a discussion of Refinement Types for Kotlin.
Refinement Types allow narrowing types by specifying constraints on their values, thus enhancing type safety and reducing the number of bugs.
Design notes could be found here.
Important: This is not a proposal, we did a research on the topic, but we don't intend to bring Refinement Types to Kotlin at the moment. However, we're sharing our work to be transparent, and we'd love to hear your thoughts, suggestions, or concerns.
Beta Was this translation helpful? Give feedback.
All reactions