I'm not sure how good an idea this is, but... A f...
# compiler
I'm not sure how good an idea this is, but... A frustration of mine for ages has been the way you have to choose between compile time safety and convenience when constructing values into types - e.g. converting a
into a
. For untrusted input ideally I want a function that forces the caller to handle the bad case -
fun String.toUri(): Either<URISyntaxException, URI>
. But that's a colossal pain when constructing from a string literal; I don't want
to return an
, I want a
! Of course you can provide two methods, one for untrusted input, one for trusted, but that immediately opens up the possibility of human error choosing the wrong one. So I was wondering if a compiler plugin could actually infer that the function's arguments are known at compile time and actually call the function to prove that it returns a
, and in that case allow
val uri: URI = "<http://www.example.com>".toUri()
to compile, and throw a compile error on
val uri: URI = "not a uri".toUri()
While of course
val uri: URI = runtimeInputString.toUri()
would not compile because the return type would be
Either<URISyntaxException, URI>
Yup, that would solve all the question of whether or not the expression could be evaluated at compile time!
Typescript had a proposal for regex-validated types, which could be a decent compromise to enable this sort of behaviour without needing actual compile-time evaluation of functions. In effect you would still declare two functions, but the compiler would be able to choose between the partial one and the total one depending on what was known about the value.
If I'm writing a compiler plugin it's my problem though - and I'd like the more powerful version so I could deal with cases where regex wasn't enough.