# Allow for Compile-Time Checked Intervals for Parameters Expecting Literal Values

**URL:** <https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743>\
**Category:** Pitches\
**Created:** [July 9, 2019, 2:14am UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743 "2019-07-09T02:14:46Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![rlziii](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/rlziii/32/12167_2.png) [@rlziii](https://forums.swift.org/u/rlziii)\
**Post date:** [July 9, 2019, 2:14am UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/1 "2019-07-09T02:14:47Z")

</div>

# Introduction

Certainly methods are written to primarily accept literal values. However, when using types such as `Int` or `Double` there is no way to check at compile time that the supplied arguments are valid for a given interval/range. We must rely on run time checks that could cause for adverse side effects which may be difficult to handle.

# Motivation

Commonly method parameters are written to only allow for certain valid literal values. With finite options an `enum` can be used to limit and constraint these options. However, `enum`s are not always a great solution. Imagine the method below:

```swift
/// Set the height of a building.
/// Only numbers 1 through 10 (inclusive) are valid.
///
/// - Parameter height: The new building height with interval [1, 10]
func setHeight(_ height: Int) {
    guard height > 0, height <= 10 else {
        // What do we do here?
        //
        // Maybe return false?
        // Maybe throw an error?
        // Maybe change the return type to Optional<Bool>?
    }

    // ...
}

```

While an `enum` could be created to allow for all of the values (`1` through `10`), if the method allowed for a height between `1` and `1,000` that quickly becomes unwieldy and an abuse of `enum`s. The code as written will not catch any errors at compile time, only run time, even though we are looking for a specific set of valid literals. So there is no reasonable way to guard against a programming error in this regard.

# Proposed Solution

_NOTE_: This solution is only useful for methods that take literal parameters. Of course if a non-literal variable is expected then that can only be checked at run time (for example, if height was supplied by the user then there is no way to check for the interval at compile time of course).

This solution adds a way to construct a method to take literal values within an interval. The method displayed before can now be written as:

```swift
/// Set the height of a building.
/// Only numbers 1 through 10 (inclusive) are valid.
///
/// - Parameter height: The new building height with interval [1, 10]
func setHeight(_ height: Int[1...10]) -> Bool {
    // We can check for the height at compile time now instead of run time
}

```

The above method will require that `height` be a literal or constant value; a variable cannot be passed in (a compile time error would have to occur in this case).

Regular Swift range syntax would also apply here: `[1..<5]` would allow for the numbers `1`, `2`, `3`, and `4` (since `5` in this case is not inclusive). And for more than just `Int`s: `[0.0...5.0]` would allow for anything between `0.0` and `5.0` (inclusive).

---

<div class="post-metadata">

**Author:** ![rauhul](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/rauhul/32/35207_2.png) [@rauhul](https://forums.swift.org/u/rauhul)\
**Post date:** [July 9, 2019, 2:25am UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/2 "2019-07-09T02:25:20Z")

</div>

I think what you're pitching is a much reduced form of [Dependent Types](https://en.wikipedia.org/wiki/Dependent_type). This is also a feature I would love to see in swift and find myself reaching for all the time.

There has been some previous discussion on the topic, see:

> [@\[Generics\] \[Pitch\] Dependent Types](https://forums.swift.org/t/generics-pitch-dependent-types/6748):
>
> Hi swift-evolution, I’ve been thinking for the past months of making math libraries that could benefit from a dependent types system (see the Wikipedia article: [Dependent type - Wikipedia](https://en.wikipedia.org/wiki/Dependent_type?wprov=sfti1%5C)). Dependent types would allow for the type system to enforce certain correctness in design that otherwise would have to be test-based. It would also discourage type hacks that sort of implement it, but have poor semantics and clarity. Lemme give you an example: - Let’s say you want to make a modulo arit…

Syntactically I think it would make more sense to write the value constraints using existing notation. Something like this comes to mind:

```swift
typealias Height = Int where self > 0, self <= 10

```

This is also related to previous discussion on `newtype` functionality, see [here](https://forums.swift.org/t/a-kernel-of-another-newtype-idea/26475).

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [July 9, 2019, 3:01am UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/3 "2019-07-09T03:01:37Z")

</div>

Better validation at compile time would benefit many types, not just those expressible by integer literals. The groundwork is being laid for this with [compile-time constant expressions](https://forums.swift.org/t/compile-time-constant-expressions-for-swift/12879).

Once built out, one imagines that a `@compilerEvaluable` precondition would get you the diagnostics you want.

See also:

- [Improved compile-time validation for types expressible by integer literals](https://forums.swift.org/t/improved-compile-time-validation-for-types-expressible-by-integer-literals/25765)
- [Search results for 'constexpr'](https://forums.swift.org/search?q=constexpr)
- [Search results for 'compilerEvaluable'](https://forums.swift.org/search?q=compilerEvaluable)

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner3](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/chris_lattner3/32/348_2.png) [@Chris\_Lattner3](https://forums.swift.org/u/Chris_Lattner3)\
**Post date:** [July 9, 2019, 4:58am UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/4 "2019-07-09T04:58:29Z")

</div>

+1 to @xwu's point. IMO this is best modeled by having the compiler evaluable work trace through normal asserts, producing a static compile time error when it can prove that a call will always fail. This would also be useful for a number of metaprogramming related things.

---

<div class="post-metadata">

**Author:** ![CTMacUser](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ctmacuser/32/1802_2.png) [@CTMacUser](https://forums.swift.org/u/CTMacUser)\
**Post date:** [July 15, 2019, 2:05pm UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/5 "2019-07-15T14:05:36Z")

</div>

So this would be the `newtype` idea, except the method that filters out illegal values needs to be `constexpr` whenever possible?

---

<div class="post-metadata">

**Author:** ![GetSwifty](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/getswifty/32/39108_2.png) [@GetSwifty](https://forums.swift.org/u/GetSwifty)\
**Post date:** [July 15, 2019, 8:40pm UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/6 "2019-07-15T20:40:22Z")

</div>

Dependent Types in some form or fashion is something I've been interested in being added to Swift for a while, so glad to see some more interest/movement on this!

Having more comprehensive compile-time checks for things like 0 division, passing percentages, or passing degrees seems like the ideal way to prevent those types of user errors.

In addition to the literal checking, it would be great if the compiler could check whether a variable has been verified as being valid before the function was called. e.g. (pseudo code)

```swift
setHeight(height) // error because the variable wasn't checked
if [1...10].contains(height) {
    setHeight(height) // no error because the variable was checked.
}

I think it makes sense to start with a more generic compile-time-check API like @xwu mentioned, and then later add some syntactic sugar once there's a good idea what types of things are often being checked.
```

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [July 15, 2019, 8:43pm UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/7 "2019-07-15T20:43:38Z")

</div>

a good place to start would be defining a wrapper type `Digit` around `Int` that can only be initialized from literals in the range `1 ... 10`. Right now you can do this with a run-time check though a compile-time check would be better. Then you should implement `+`, `-`, `*`, `/`, `%`, etc to trap if they would produce an out-of-range result. This is heavy and unwieldy, but the only sound implementation. I do think though that we could automate this at least partially,, for example we could synthesize such a wrapper using @rauhul ’s `syntax

```swift
typealias Height = Int where self > 0, self <= 10

```

and let it get implicitly upcast to its backing type instead of needing to drill down into a `.value` member. in fact, this is sounding suspiciously like a property wrapper, and could probably be implemented as such, if the variable you’re trying to constrain is bound to a type scope.

---

<div class="post-metadata">

**Author:** ![CTMacUser](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ctmacuser/32/1802_2.png) [@CTMacUser](https://forums.swift.org/u/CTMacUser)\
**Post date:** [July 20, 2019, 7:58am UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/8 "2019-07-20T07:58:31Z")

</div>

> [@rauhul](#):
>
> Syntactically I think it would make more sense to write the value constraints using existing notation. Something like this comes to mind:
> 
> ```
> typealias Height = Int where self > 0, self <= 10
> 
> ```

It shouldn't use "`typealias`." The reason is in its name; the facility does not create a new type that is a 100% copy of another, it just references an existing type. (AIUI, creating a functions with signatures that differ by switching a type with an alias would be an illegal redeclaration, not an overload.) But adding constraints to an existing type **must** fundamentally create a new distinct (albeit related) type. So using the "`typealias`" word for this capability would be confusing (a.k.a. lying) to the user.

The syntax reminds me of Ada's subtype syntax. I've been looking at a manual for research, but Ada has a different type philosophy that makes the subtype syntax work for it but would be a bad fit for us. (Ada has many built-in types, with sets of operations, and subtyping built in. Your first type declaration declares a type class and its initial no-constraint subtype. We moved those types totally within the Standard library, enabled with the `struct`/`enum`/`class` facilities, so we need to handle subtypes/dependent-type/reduced-state-types differently.)

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [July 21, 2019, 4:24am UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/9 "2019-07-21T04:24:41Z")

</div>

## TL;DR

Protocols express the requirements to _be_ something. Types express the notion that a thing _is_ something. Constraints (constexpr or otherwise) express the requirements to _be used for_ something. Depending on what you want in any specific situation, you choose the appropriate of those three mechanisms. Examples like the aforementioned ‘Height’ one tend indeed to want for [constexpr] constraints.

## Reasons

It’s interesting (and complicating) that what this is trying to express is not just typy nor just protocolly. In some sense you’re just trying to say “I want an Int that meets these requirements” - which sounds protocolly, but then when you think about it, does it make sense to have a `Height` protocol in the traditional sense, i.e. where technically it can be _any_ type, not just an `Int`? In a _pure_ Protocol world that could make sense, since `Int` would merely be a _protocol_ that expresses the _idea_ of a thing which has the set of properties & capabilities that distinguish an integer. But that’s nowhere near what Swift is today, and seems obviously not a place Swift will ever go.

If you nonetheless try pragmatically to just add the ability to require specific typeness to protocols, e.g.:

```
protocol Height: Int where self > 0, self < 10 {}

```

Or:

```
protocol Height where Self is Int, self > 0, self < 10 {}

```

There’s all sorts of awkward things about that. It blurs the lines between types & protocols, for one. You haven’t actually _conformed_ `Int` to the protocol either, yet - you’d have to add the extension to `Int` as well, which is a lot of redundancy & boilerplate. And in principle, since it’s a protocol, you can put all the normal protocol stuff between the curly braces, which… well, probably that’s actually useful in some cases, but it doesn’t negate the prior concerns and might amount to feature creep.

So that suggests this should be a bit more typy, e.g.:

**subtype** Height **is** Int **where self** \> 0, **self** \< 10

That seems much cleaner at the outset (even though it still blurs typiness & protocolness a bit).

A new keyword & associated concept would be required, as opposed to repurposing `typealias` or similar, because of the need to support _any_ type, not just classes, as well as the fact that this is _not_ merely an alias (as @CTMacUser pointed out). I think it’s also best to be distinct, syntactically, vs subclassing - i.e. not go down the route of allowing:

```
struct Foo {
    ...
}

struct SubFoo: Foo where self > 0

```

It’s too close to subclassing, and thus people will forever be misguided into wanting support for all the rest of subclassing’s capabilities (new properties, new functions, overrides, etc), which don’t make sense by definition for a constraining subtype (nor value types in general in the presence of the `extension` keyword & mechanism).

Alternatively there is a ‘wrapper’ approach, where you declare e.g. ‘Height’ as a new type which stores an `Int` internally and applies the conformances through constexpr constraints specifically on its `init` method(s), but that’s an impractical amount of boilerplate for any non-trivial base type, e.g.::

```
struct Height {
    private var actualValue

    init(_ value: Int) where value > 0, value < 10 {
        self.actualValue = value
    }
}

// And now a bajillion extensions to make Height conform to all the protocols
// expected of an Int, assuming there even are protocols to fully cover what
// an Int is (hint: there aren’t, today)...

// ...and you still have to do “myHeight.asInt” or somesuch everywhere you need
// to use virtually any existing code, since `Int` is a type, not a protocol. This
// approach is very hostile to the extensions paradigm.

```

So, given all that a `subtype` keyword et al seems like the best approach (at least vs protocols or wrappers).

Then, several obvious questions are:

### Do `subtype`s manifest as new `Metatype`s?

My intuition is that they should, for several reasons:

- Code that calls `type(of: ...)` and the like, and certainly anything that conveys the type of the thing to a human, would be more intuitive to call it a `Height` than an `Int`. It would also be a valuable distinction in reasoning about code using generics or compound types, since while _technically_ an e.g. array of `Height`s and an array of `Int`s would be equivalent at runtime, semantically they are distinct.

- Being able to runtime conditionalise behaviour based on _compile-time ensured_ and stated compliance to a subtype could be useful just as it can be useful to downcast class instances. e.g.:

- You can then more sensibly require explicit upcasting (i.e. requiring `someHeight as Int` whenever you pass the value to a parameter expecting an `Int`), because the true type would be preserved under the covers, allowing for downcasting back to the leaf type at any later stage (if needed).

### What does `<some Height> + <some Int>` do?

The resulting type cannot unconditionally meet the requirements, since the addition could produce a value that’s outside the requirements of `Height`. A reasonable default would therefore be to pick the least specific type, i.e. `Int` in this case, but that means we’ve added (back) into Swift implicit type conversion, essentially (granted it’s an upcast, not a lateral cast, but still).

But furthermore consider, instead of an operator, what about a method on `Int` that returns `Int` - what does that do when called on an `Int` that is specifically a `Height`? Does it still return an `Int`? It would have to - we can’t unilaterally guarantee that the result of all methods on `Int` that return `Int` (or `Self` if expressed that way) would actually return a value conforming to `Height`. And it would be a bit absurd to have to do `(myHeight as Int).someMethodOrProperty` for all such methods - you should just use the ‘wrapper’ pattern at that point, without any new language support needed.

And any mechanism that would require `Height` to override every such method in order to ensure the returned values are also `Height`s is impractical if not impossible - for example, how would it handle a `negated` method sanely when the result is naturally not a valid `Height`, but the method on `Int` is not declared with `throws` nor returns `Optional` or the like. Etc.

So logically any method on the parent type:

- Cannot implicitly return the subtype (not even via `Self` or any other such genericness).
- Must nonetheless be supported on instances of the subtype _without_ any extra boilerplate.

So at that point, what’s the point? Anything you do to a `Height` will turn it “back” into a raw `Int`, and that tiny remaining functionality - of semantic distinction in passing values around unmodified - can easily be achieved using a wrapper type.

Alternatively, if the compiler were willing to sort of ‘dynamically’ change the method signatures - e.g. automatically make throwable or the return value `Optional` any methods which aren’t provably going to return a a valid `Height` - then I guess that could work… but that’d be a pretty complicated task for the compiler (and might require constexpr and similar advancements first, anyway)...

### Conclusion (?)

...all of which seems to lead to the apparent conclusion that this should _not_ be implemented by actual subtyping (nor protocols), but instead ‘merely’ via constraints on values at their individual use sites (e.g. via constexprs).

What we then need is a way to declare a ‘macro’ for those constraints, to get comparable convenience & benefits to the `subtype` approach, e.g.:

```
constexpr func IsValidHeight(_ value: Int) -> Bool {
    return value > 0 && value < 10
}

...

func someFunc(_ value: Int) where IsValidHeight(value) {
    ...
}

```

Though naturally you still want to be able to apply the same constraints to stored values’ types, and now we discover an infinite loop since the apparent way to do that would be something like:

```
<some keyword> Height = Int where IsValidHeight(self)

```

That’s really just a convenient ‘macro’ for, at every stored value declaration:

```
var height: Int where IsValidHeight(height)

```

And then if you think about it _that_ way, maybe `typealias` really is essentially all that’s needed (given constexprs)…?

### Addendum

In any case, what actually interests me - beyond just ‘plain’ constexprs - is the idea that the Swift compiler could automatically de-try and de-Optional based on parameter analysis & the function’s implementation, where appropriate (i.e. not across boundaries that are supposed to represent stable APIs). This wouldn’t be a replacement for any of the above necessarily, but could be complimentary, e.g.:

```
func setHeight(_ value: Int) throws {
    guard let height = value where value > 0 && value << 10 else {
        throw SomeError
    }

    ...
}

...

setHeight(5) // Look ma, no ‘try’!

```

Swift knows the argument ‘5’ can’t cause an exception by static analysis, so it allows the ‘try’ to be elided. That’s the ‘carrot’ side - the ‘stick’ side could be similarly enhanced vs today:

```
try! setHeight(11) // Compile-time error: Swift knows it will always throw and therefore always abort.
try? setHeight(11) // Compile-time warning: Swift knows it will always throw.
// The try? case could even detect that `setHeight` has no side-effects, omit code for it
// entirely, plus warn that the statement has literally no effect.

```

To me that seems like a much bigger win in practice (even if it only works within a single module, as my intuition suggests, without more effort from the compiler and/or programmer).

Then, adding constexpr to the mix generalises this fully.

---

<div class="post-metadata">

**Author:** ![Alejandro\_Martinez](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alejandro_martinez/32/821_2.png) [@Alejandro\_Martinez](https://forums.swift.org/u/Alejandro_Martinez)\
**Post date:** [July 23, 2019, 11:54am UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/10 "2019-07-23T11:54:54Z")

</div>

> [@rauhul](#):
>
> ```swift
> typealias Height = Int where self > 0, self <= 10
> 
> ```
> 
> This is also related to previous discussion on `newtype` functionality, see [here](https://forums.swift.org/t/a-kernel-of-another-newtype-idea/26475).

I like this syntax because it makes it more generic (except the wrongly used typealias keyword) and would be in favour of getting us closer to the newtype ideas.

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [July 24, 2019, 5:35am UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/11 "2019-07-24T05:35:53Z")

</div>

How about:

**constrainedtype** Height = Int **where self** \> 0, **self** \<= 10

In use:

```
var height: Height

func setHeight(_ value: Height) {
  …
}

```

It's perhaps just syntactic sugar for:

```
var height: Int where height > 0, height <= 10

func setHeight(_ value: Int) where value > 0, value <= 10 {
  …
}

```

Seems like a fairly simple but rewarding bit of sugar.

---

<div class="post-metadata">

**Author:** ![Jean-Daniel](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@Jean-Daniel](https://forums.swift.org/u/Jean-Daniel)\
**Post date:** [July 24, 2019, 8:12am UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/12 "2019-07-24T08:12:26Z")

</div>

What can you do with this new type ? I guess it won't be possible to even use basic operator like `+`

```swift
var h1: Height = 8
var h2: Height = 8
var h3: Height = h1 + h2

```

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [July 24, 2019, 2:40pm UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/13 "2019-07-24T14:40:55Z")

</div>

See also [my prior post where](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/9) I talked about that.

In this case - as opposed to `Height` truly being a distinct subtype - it's all `Int` underneath, so there's technically no ambiguity or complication about what the `+` operator works on or returns - all still `Int`s. It's only the assignment to `h3` that's questionable, as that's when the constraints on the `Height` type are evaluated and need to be followed. If the compiler cannot verify those constraints at compile-time, it would have to disallow the assignment.

Alternatively, the compiler might - instead of erroring out unconditionally - implicitly demote any such unclear constraint checks to runtime by turning the operation into a throwing one, thus requiring the code author to use `try!` / `try?` / etc to handle the possible constraint failures at runtime.

So the code would have to be:

```
var h1: Height = 8
var h2: Height = 8

guard try var h3: Height = h1 + h2 else {
  …
}

```

Or something to that effect.

For mutating operators it'd have to be something like:

```
var h1: Height = 8
try {
  h1 += 2
} catch ConstraintViolation {
  …
}

```

Etc.

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [July 24, 2019, 4:37pm UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/14 "2019-07-24T16:37:32Z")

</div>

Integer overflows trap in Swift

---

<div class="post-metadata">

**Author:** ![rauhul](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/rauhul/32/35207_2.png) [@rauhul](https://forums.swift.org/u/rauhul)\
**Post date:** [July 24, 2019, 5:07pm UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/15 "2019-07-24T17:07:06Z")

</div>

> [@Nevin](#):
>
> Integer overflows trap in Swift

I don't think this is relevant here; I think `Height` is a constrained form of `Int`, but not a distinct type and anything that would trap on `Int` should fail in the same ways on `Height`.

* * *

> [@wadetregaskis](#):
>
> ```swift
> var h1: Height = 8
> var h2: Height = 8
> 
> guard try var h3: Height = h1 + h2 else {
> …
> }
> 
> ```
> 
> Or something to that effect.

This does not feel like the right use of `try`. If the compiler cannot statically prove that the result of a function does not meet the constraints of the type its being assigned to be, it should emit an error.

* * *

@Jean-Daniel's example should be an error. Please ignore the actual error descriptions, I'm sure someone else can find a better way to describe them.

```swift
let h1: Height = 8
let h2: Height = 8
let h3: Height = h1 + h2 // The result of `h1 + h2` does not satisfy the requirements of `Height`.

```

In the case where the compiler cannot statically determine if the expression's result would meet `Height`s constraints it should emit an error kinda like this:

```swift
func (h1: Height, h2: Height) -> Height {
    let h3: Height = h1 + h2 // Cannot statically prove the result of `h1 + h2` satisfies the requirements of `Height`, please insert a run-time check.
    return h3
}

```

With this error in mind the user could change their code to:

```swift
func (h1: Height, h2: Height) -> Height {
    let result: Int = h1 + h2
    // result: 0...20
    guard result <= 10 else { return 10 }
    // result: 0...10    
    return result
    // returning result is fine here because it meet all requirements on `Height`
}

```

What matters here is that the user knows they need to find a way to tell the compiler the result of their expression meets the (`typealias`/`subtype`/`newtype`)'s constraints.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [July 24, 2019, 5:22pm UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/16 "2019-07-24T17:22:39Z")

</div>

> [@rauhul](#):
>
> > Integer overflows trap in Swift
> 
> I don't think this is relevant here; I think `Height` is a constrained form of `Int` , but not a distinct type and anything that would trap on `Int` should fail in the same ways on `Height` .

The behavior is inherent to the operator, not the type. When `+` overflows, it traps.

> [@rauhul](#):
>
> In the case where the compiler cannot statically determine if the expression's result would meet `Height` s constraints it should emit an error kinda like this:

It should not. When `+` overflows, it traps--those are the semantics of the operator.

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [July 24, 2019, 5:52pm UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/17 "2019-07-24T17:52:56Z")

</div>

> [@rauhul](#):
>
> > [@wadetregaskis](#):
> >
> > ```swift
> > var h1: Height = 8
> > var h2: Height = 8
> > 
> > guard try var h3: Height = h1 + h2 else {
> > …
> > }
> > 
> > ```
> > 
> > Or something to that effect.
> 
> This does not feel like the right use of `try`. If the compiler cannot statically prove that the result of a function does not meet the constraints of the type its being assigned to be, it should emit an error.

In some sense that’s an orthogonal debate. For the purposes of this thread, either approach is viable.

As someone that writes code that has non-zero deployment latency and that is used by someone other than myself, my code not crashing is pretty much a necessity. Anything that traps or aborts is a horrible design flaw or simple bug to me.

“Give up and explode” is a rational strategy only in extreme cases where there’s a significant probability that program integrity truly has been compromised. That used to be pervasive in prior C-family languages in large part because so many operations were memory unsafe, but Swift makes those much rarer. Overflow of an addition cannot possibly justify unconditionally killing the current process. That Swift does this today is a design “flaw” IMO (though only for lack of a known better approach…). And not even handled gracefully by Apple’s own tools - e.g. the following code crashes the Swift Playground iOS app:

```
var a: UInt8 = 255
var b: UInt8 = 2
a + b

```

I think the trapping behaviour was purely because nobody wants to have to write `try` for every integer operation et al, which is a totally reasonable compromise. In practice it’s not usually a huge deal because integers are pretty big containers and overflow is rare. But once we start adding constraints that reduce their scales massively - as in this `Height` example where the ‘int\_max’ becomes essentially just _ten_, overflow - if not otherwise caught - would be literally a million times more likely.

Thus why it’s completely unacceptable to treat constraint violations as overflows, at least insofar as they cause unconditional process abort.

Beyond that, I always prefer that the compiler not _require_ complete compile-time assurances wherever possible (e.g. where it doesn’t impose unreasonable burden, as it seemingly would with basic integer operators), because my suspicion is that will make life very difficult for code authors just like any hard compile-time requirements are. Swift as a language clearly prefers to to defer problem handling to runtime, via exceptions, where necessary.

It also allows the code author to make the choice, rather than forcing it on them, since they can always just use `try!` if “give up and explode” is a viable strategy for them.

Or put another way, I prefer a _little_ bit of Python-style “well, I’ll let you try, good luck” vs e.g. C++ or Rust’s “you’re going to sit here and fight with me for six hours until I’m satisfied, _then_ you can have your app”.

---

<div class="post-metadata">

**Author:** ![Jean-Daniel](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@Jean-Daniel](https://forums.swift.org/u/Jean-Daniel)\
**Post date:** [July 24, 2019, 6:07pm UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/18 "2019-07-24T18:07:15Z")

</div>

> [@wadetregaskis](#):
>
> Overflow of an addition cannot possibly justify unconditionally killing the current process. That Swift does this today is a design flaw IMO.

How many time have you considered what will append in case of overflow while design an algorithm using interger ?

The answer is easy, almost nobody think about that, that why there is a lot of security vulnerability caused by integer overflow, and so why it should trap by default.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [July 24, 2019, 6:52pm UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/19 "2019-07-24T18:52:49Z")

</div>

> [@wadetregaskis](#):
>
> Thus why it’s completely unacceptable to treat constraint violations as overflows, at least insofar as they cause unconditional process abort.

Again, that behavior is inherent to the semantics of `+`, which are not changeable at this point. You can have an operator that exhibits a different behavior, but it cannot then be spelled `+`.

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [July 24, 2019, 9:10pm UTC](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743/20 "2019-07-24T21:10:55Z")

</div>

> [@xwu](#):
>
> > [@wadetregaskis](#):
> >
> > Thus why it’s completely unacceptable to treat constraint violations as overflows, at least insofar as they cause unconditional process abort.
> 
> Again, that behavior is inherent to the semantics of `+`, which are not changeable at this point. You can have an operator that exhibits a different behavior, but it cannot then be spelled `+`.

Can you elaborate on why these arithmetic operators _have_ to trap if one of these type constraints is violated?

[Next page](https://forums.swift.org/t/allow-for-compile-time-checked-intervals-for-parameters-expecting-literal-values/26743.md?page=2)
