x: 1..100
y: "yes" | "no"
I feel that there are lots of low hanging fruits when it comes to typing which would improve both program readability and correctness. x: 1..100
y: "yes" | "no"
I feel that there are lots of low hanging fruits when it comes to typing which would improve both program readability and correctness.[0] https://en.wikipedia.org/wiki/Refinement_type [1] https://goto.ucsd.edu/~ucsdpl-blog/liquidtypes/2015/09/19/li... [2] https://goto.ucsd.edu/~rjhala/liquid/liquid_types.pdf [3] https://ucsd-progsys.github.io/liquidhaskell/ [4] https://github.com/flux-rs/flux
The former is difficult to track through arithmetic operations.
X: 1 | 2 | 3 // … type N = 1 | 2
const x1:N = 1
const x2:N = 1
const sum:N = x1 + x2
Typescript (the version running on my box) considers this an error.Typescript is able to do this with strings when using templates.
type Suit = "C" | "D" | "H" | "S";
type Rank = "A" | "2" | "3" | "4";
type Card = `${Suit}${Rank}`;
const club = "D";
const ace = "A";
const aceOfClubs: Card = `${club}${ace}`;
Even though I have not declared the club or ace as a Suit or Rank, it still infers the Card correctly in the last line. This is a stronger form of typing than what you are settling for where 1..100 doesn't know its own range.This is the difference I'm referring to.
>There is nothing to suggest that 1..100 understands math.
That's like, your opinion man. I'd like it.
For operations/mutations where it's more complex to validate the inputs, you could assign the result to an unbounded variable, and then prove to the type checker that you're exhaustively handling the output before you assign it to a bounded variable. For example, multiply two unbounded numbers, store the result in an unbounded variable, then do "if result >= 1 && result <= 100 then assign result to var[1..100] else .... end"