<p>I've just watched an interview on YouTube with Simon Peyton Jones where they talk about Epic's Verse language. <a href="https://youtu.be/UBgam9XUHs0?si=A7hvtzBD0zZC_d9_&amp;t=3092" rel="noreferrer">Here</a> (at roughly 51:30) they start talking about the type system.</p>
<p>Simon mentions that Verse's version of type checking (he calls it verification) is done via functions written in Verse. These functions have to be side-effect free and receive one value as an argument. This argument is then checked inside this function of whether it adheres to the spec of the type we want to define and either succeeds with a certain value (the type checks out) or fails (it doesn't type-check).</p>
<p>For example, to define a type <code>even</code> that only accepts even integers, I could write something along these lines (using Haskell here since I'm not familiar enough with Verse):</p>
<pre class="lang-hs prettyprint-override"><code>int x = True -- pseudo function to check whether a value is an integer

even x | int x &amp;&amp; x `mod` 2 == 0 = x
       | otherwise = error &quot;doesn't type check&quot;

-- pseudo Haskell
x :: even
x = 1 -- uneven, type error
x = 2 -- even, ok
</code></pre>
<p>Now this is a fairly easy example where a compiler could figure this out statically (I guess this is what refinement types are?), but what happens if the compiler cannot see the value of <code>x</code> (e.g. it's read from stdin at runtime)?</p>
<p>At <a href="https://youtu.be/UBgam9XUHs0?si=2qCLv3xhqwHrmUqb&amp;t=3215" rel="noreferrer">53:35</a> in the interview, Simon then explains some of the benefits of static type checking and how Verse approaches this topic. He then says, that the verifier can either accept or fail a type test, but it (in my opinion) sounds like failing verification doesn't necessarily result in the program being rejected by the compiler (see <a href="https://youtu.be/UBgam9XUHs0?si=1wQEPhGV7SJjzE0n&amp;t=3300" rel="noreferrer">55:00</a>). Does this mean that there will be some sort of type checking happening at runtime? Or does he just mean that type checking can fail for rather arbitrary/opaque reasons until the verifier is more fleshed out?</p>
<p><em>Disclaimer: I'm not an expert in PL design, so I might've gotten some details wrong. I apologize in advance.</em></p>

<static-typing><type-checker><gradual-typing>
Is Epic Games' Verse gradually typed?
CC BY-SA 4.0
2024-02-02T14:20:49.137Z
Perhaps you mean [refinement types](https://en.wikipedia.org/wiki/Refinement_type) (more details or constraints on the types of some variables) instead of gradual typing (ability to add and remove typing annotations to code)?
Pablo H
CC BY-SA 4.0
2024-02-02T19:36:45.807Z
@PabloH I'm a little bit familiar with refinement types, but my question was more about whether Verse will have runtime type checking. I came up with the title after searching for tags and stumbling across [gradual-typing]. The tag description sounded like what I had in mind so I added it to the title without looking up the term properly.
Timo
<p>It's worth noting that gradual typing <em>does not</em> mean checking types at run time (in either direction). Verse is not gradually-typed because it <a href="https://dev.epicgames.com/documentation/en-us/uefn/common-types-in-verse" rel="noreferrer">does not permit untyped code to exist</a>: &quot;a type is assigned to every identifier&quot;.</p>
<p>The purpose of verification of this sort is to allow expressing complex constraints on values that are fairly straightforward to write code for, but hard to describe out of typical type combinators. These could represent calculations on numbers or strings (&quot;starts with <code>&lt;</code> and ends with <code>&gt;</code>), constraints on multiple values (&quot;<code>x</code> is within the range of indices of array <code>y</code>), and so on. The compiler will attempt to confirm that the predicate is always true, based on the knowledge it has about the program state at the relevant point.</p>
<p>The portion of the discussion you link to at 55:00 does not seem to be suggesting that unverified programs can run at all, but in fact explicitly saying the opposite.</p>
<blockquote>
<p>Unlike Haskell, there won't be a clean bright line between programs that can be verified and programs that can't, right, because it'll be a function of just how smart the verifier has become. On any one day we might hope to characterise as precisely as possible where that boundary lies, but it is a boundary that will move over time.</p>
</blockquote>
<p>The point is that future advancements in the verifier may permit additional predicates to be verified, or additional code to be confirmed as meeting the requirements that couldn't be today. The example given earlier is knowing that <code>x^2</code> is always non-negative — the verifier may not know that today, and so not allow that expression to be assigned to a natural-number variable, but a future version that had the &quot;<code>x^2</code> can't be negative&quot; rule included would accept <em>the same code</em>. Until then, the program would be rejected as unverifiable.</p>
<p>It even goes on to discuss hypothetical user-controlled extensions where the user might add a false rule, and notes that this could cause the program to crash in a horrible way; this is not a concern if you're already allowing unverified programs to run!</p>
<p>In your example, if the compiler cannot see the value of <code>x</code>, and doesn't have any guarantee from elsewhere that it must be an even number, then verification fails, and the program is rejected.</p>
<hr />
<p>There <em>are</em> languages using this sort of verification that do permit deferring some checks to run time, and crash in a controlled way if they are found not to be met. Even then, it's usually seen as a stopgap. Verse does not appear to be one of those, and I wouldn't consider the ones that do to be gradually-typed either; the gradual typing people have <a href="https://drops.dagstuhl.de/entities/document/10.4230/LIPIcs.SNAPL.2015.274" rel="noreferrer">very specific ideas</a> of what that term means and it fundamentally requires that removing annotations is possible without affecting program behaviour.</p>

CC BY-SA 4.0
2024-02-01T20:28:09.560Z
2024-02-01T20:28:09.560Z
Michael Homer
CC BY-SA 4.0
2024-02-01T22:27:41.630Z
Thanks for the elaborate answer, that clears things up. I have one follow up question regarding your response to my `even` example. You said: *"and doesn't have any guarantee from elsewhere that it must be an even number, then verification fails"*. Does that mean that if I were to put, say, an `if` check around the definition of `x` which checks for the same constraints that my `even` type does ([example](https://play.haskell.org/saved/41ZAUrRs)), the verifier would (theoretically) accept it?
Timo
CC BY-SA 4.0
2024-02-01T22:46:35.287Z
It might! That's one of the rules that the verifier could know about, and basic knowledge of conditionals is very common, but it also needs to understand the condition itself. It could also be that some other information is known about `x` that necessarily implies `even`, for example if it came from an unknown integer multiplied by another even number. All of these other cases are what SPJ is talking about when he says it depends on how smart the verifier has become — it doesn't know this now, but a future version could learn that `x = y*z ⇒ mod x z ==0` and start to accept the program.
Michael Homer
CC BY-SA 4.0
2024-02-02T16:35:52.687Z
I presume that there are limits to how "smart" it can be -- perfect verification is likely equivalent to the halting problem.
Barmar
# Is Epic Games' Verse gradually typed?
Posted by: username_0 on 2024-02-01
I've just watched an interview on YouTube with Simon Peyton Jones where they talk about Epic's Verse language. Here (at roughly 51:30) they start talking about the type system.
Simon mentions that Verse's version of type checking (he calls it verification) is done via functions written in Verse. These functions have to be side-effect free and receive one value as an argument. This argument is then checked inside this function of whether it adheres to the spec of the type we want to define and either succeeds with a certain value (the type checks out) or fails (it doesn't type-check).
For example, to define a type even that only accepts even integers, I could write something along these lines (using Haskell here since I'm not familiar enough with Verse):
int x = True -- pseudo function to check whether a value is an integer

even x | int x && x `mod` 2 == 0 = x
       | otherwise = error "doesn't type check"

-- pseudo Haskell
x :: even
x = 1 -- uneven, type error
x = 2 -- even, ok

Now this is a fairly easy example where a compiler could figure this out statically (I guess this is what refinement types are?), but what happens if the compiler cannot see the value of x (e.g. it's read from stdin at runtime)?
At 53:35 in the interview, Simon then explains some of the benefits of static type checking and how Verse approaches this topic. He then says, that the verifier can either accept or fail a type test, but it (in my opinion) sounds like failing verification doesn't necessarily result in the program being rejected by the compiler (see 55:00). Does this mean that there will be some sort of type checking happening at runtime? Or does he just mean that type checking can fail for rather arbitrary/opaque reasons until the verifier is more fleshed out?
Disclaimer: I'm not an expert in PL design, so I might've gotten some details wrong. I apologize in advance.
**Tags:** static-typing type-checker gradual-typing
> **Comments:**
> **username_1**: Perhaps you mean [refinement types](https://en.wikipedia.org/wiki/Refinement_type) (more details or constraints on the types of some variables) instead of gradual typing (ability to add and remove typing annotations to code)?  
> **username_0**: @PabloH I'm a little bit familiar with refinement types, but my question was more about whether Verse will have runtime type checking. I came up with the title after searching for tags and stumbling across [gradual-typing]. The tag description sounded like what I had in mind so I added it to the title without looking up the term properly.  
---
## 1 answers
### Answer by username_2 on 2024-02-01. Score: 11 | Accepted answer
It's worth noting that gradual typing *does not* mean checking types at run time (in either direction). Verse is not gradually-typed because it [does not permit untyped code to exist](https://dev.epicgames.com/documentation/en-us/uefn/common-types-in-verse): "a type is assigned to every identifier".

The purpose of verification of this sort is to allow expressing complex constraints on values that are fairly straightforward to write code for, but hard to describe out of typical type combinators. These could represent calculations on numbers or strings ("starts with `<` and ends with `>`), constraints on multiple values ("`x` is within the range of indices of array `y`), and so on. The compiler will attempt to confirm that the predicate is always true, based on the knowledge it has about the program state at the relevant point.

The portion of the discussion you link to at 55:00 does not seem to be suggesting that unverified programs can run at all, but in fact explicitly saying the opposite.

> Unlike Haskell, there won't be a clean bright line between programs that can be verified and programs that can't, right, because it'll be a function of just how smart the verifier has become. On any one day we might hope to characterise as precisely as possible where that boundary lies, but it is a boundary that will move over time.

The point is that future advancements in the verifier may permit additional predicates to be verified, or additional code to be confirmed as meeting the requirements that couldn't be today. The example given earlier is knowing that `x^2` is always non-negative — the verifier may not know that today, and so not allow that expression to be assigned to a natural-number variable, but a future version that had the "`x^2` can't be negative" rule included would accept *the same code*. Until then, the program would be rejected as unverifiable.

It even goes on to discuss hypothetical user-controlled extensions where the user might add a false rule, and notes that this could cause the program to crash in a horrible way; this is not a concern if you're already allowing unverified programs to run!

In your example, if the compiler cannot see the value of `x`, and doesn't have any guarantee from elsewhere that it must be an even number, then verification fails, and the program is rejected.

---

There *are* languages using this sort of verification that do permit deferring some checks to run time, and crash in a controlled way if they are found not to be met. Even then, it's usually seen as a stopgap. Verse does not appear to be one of those, and I wouldn't consider the ones that do to be gradually-typed either; the gradual typing people have [very specific ideas](https://drops.dagstuhl.de/entities/document/10.4230/LIPIcs.SNAPL.2015.274) of what that term means and it fundamentally requires that removing annotations is possible without affecting program behaviour.
> **Comments:**
> **username_0** (2024-02-01): Thanks for the elaborate answer, that clears things up. I have one follow up question regarding your response to my `even` example. You said: *"and doesn't have any guarantee from elsewhere that it must be an even number, then verification fails"*. Does that mean that if I were to put, say, an `if` check around the definition of `x` which checks for the same constraints that my `even` type does ([example](https://play.haskell.org/saved/41ZAUrRs)), the verifier would (theoretically) accept it?  
> **username_2** (2024-02-01): It might! That's one of the rules that the verifier could know about, and basic knowledge of conditionals is very common, but it also needs to understand the condition itself. It could also be that some other information is known about `x` that necessarily implies `even`, for example if it came from an unknown integer multiplied by another even number. All of these other cases are what SPJ is talking about when he says it depends on how smart the verifier has become — it doesn't know this now, but a future version could learn that `x = y*z ⇒ mod x z ==0` and start to accept the program.  
> **username_3** (2024-02-02): I presume that there are limits to how "smart" it can be -- perfect verification is likely equivalent to the halting problem.  
---
