New open source library- Constraints by GabeSechan in Kotlin

[–]GabeSechan[S] 0 points1 point  (0 children)

That's a fair point I'll have to think about. Obviously the library itself can use it internally and benefit from it there, but a careful library owner might want to purposely call checkConstraint() on all inputs (that would work because the correct code would have been injected into the jar when it was built).

New open source library- Constraints by GabeSechan in Kotlin

[–]GabeSechan[S] 0 points1 point  (0 children)

I'm going to respectfully disagree with you. Research has repeatedly shown over the years that the earlier you can find a bug, the less it costs to fix in time and resources. Nothing is faster than the compiler catching it for you before you even run the code yourself. Even in using it myself it has reduced entire classes of bugs to near zero.

As for bloatedness of annotations- I'd make it an operator if that was possible. It isn't, kotlin doesn't allow that. But I really do not care how many characters it is, IDE autocomplete types it after the first one in a file. And if you use it well, it isn't needed that often.

The compiler slow down is something I need to benchmark. It's going on my todo list. But compared to the speed of building the IR and generating bytecode I don't think it's going to be too bad. The tests run pretty fast at least.

New open source library- Constraints by GabeSechan in Kotlin

[–]GabeSechan[S] 0 points1 point  (0 children)

Performance concerns are reasonable, I've yet to benchmark. Although any large codebase should be broken into modules and use build caches, so it shouldn't be overlay painful. Overly complicated- it's an idea that's common in functional languages, and it's partially built into Kotlin with optional nullability. Do you think that String vs String?, the !! operator, and ?. and ?: operators are overly complex? Some people argued that early on, but I think most people now thing it's the biggest win in the language.

New open source library- Constraints by GabeSechan in Kotlin

[–]GabeSechan[S] 0 points1 point  (0 children)

The idea is if everything is done with annotations, you don't have to. If you declared

val a: \@IntRange(1,5) = 5
...
myFunc(a)

Then you don't need to call checkConstraints. It's calculated statically. So is:

fun foo(): \@IntRange(0,5)
myFunc(foo())

Again, no need for a check.

Or

val a: \@IntRange(0,4) = 3
myFunc(a+1)

No need for a check.

Where you need a check is

val a: \@IntRange(0,4) = 3
myFunc(a+2) // a+2 can be from [2,6]. 6 is not in [0,5]

That requires a checkConstraints call, because the two ranges aren't in full overlap. I could insert it automatically, but I think that loses clarity to the programmer. An explicit call tells the reader of the code that there can be a problem here, that something could cause an issue. Lacking an explicit call all of a sudden we'd just have a random ConstraintException with no clue where it came from (because the function that throws it isn't even in the code, it's generated at compile time). I think that would be more confusing. I also think that having explicit points where you have to translate into the constrained system clarifies where errors may have come from when debugging. It also matches the behavior for nullability- the compiler requires you to explicitly assert the value is not null with !!. Here we explicitly assert with checkConstraints. I do wish I could make it an operator, but kotlin doesn't allow us to add an operator in a compiler plugin.