# Case statement won't compile

**URL:** <https://discourse.ats-lang.org/t/case-statement-wont-compile/811>\
**Category:** Google Group\
**Created:** [October 1, 2015, 9:43pm UTC](https://discourse.ats-lang.org/t/case-statement-wont-compile/811 "2015-10-01T21:43:09Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mike\_Jones](https://avatars.discourse-cdn.com/v4/letter/m/74df32/32.png) [@Mike\_Jones](https://discourse.ats-lang.org/u/Mike_Jones)\
**Post date:** [October 1, 2015, 9:43pm UTC](https://discourse.ats-lang.org/t/case-statement-wont-compile/811/1 "2015-10-01T21:43:09Z")

</div>

I had some code that worked, then after a change won’t compile, but I don’t  
understand why.

The code that compiled and worked had three value constructors and a FSS  
that switched states between two states, AtomicA and Atomic B. You can see  
this i the code here:

datatype pstate =  
| AtomicA of ()  
| AtomicB of ()  
| Hang of ()

typedef state = @{ addr= uint8, ps= pstate }  
fun process (ch:int, s: &state) : void = let  
val sn = case [s.ps](http://s.ps) of  
| AtomicA () =\> let  
val \_ = case cast{char}(ch) of  
| ‘z’ =\> let  
val \_ = do\_something()  
in s.addr := s.addr; [s.ps](http://s.ps) :=  
AtomicA end  
| \_ =\> let \_ in \_ end  
in \_ end  
| AtomicB () =\> let \_  
val \_ = case cast{char}(ch) of  
| ‘z’ =\> let  
val \_ = do\_something()  
in s.addr := s.addr; [s.ps](http://s.ps) :=  
AtomicB end  
| \_ =\> let \_ in \_ end  
in \_ end

```
          | Hang () => _

```

in  
end

Then I added two constructors, and made the transitions more complex, as  
the case for AtomicA can change to one of two states. Then it won’t compile  
and gives the error:

undefined reference to `atsruntime\_handle\_unmatchedval’

The range of lines is the entire top self case statement.

I change the top level case from “case” to “case+” and it compiles.

Can anyone explain why this makes it compile?

Note that all cases are covered because they all have a “\_” pattern at the  
bottom to match on.

datatype pstate =  
| AtomicA of ()  
| NonAtomicA of ()  
| AtomicB of ()  
| NonAtomicB of ()  
| Hang of ()

typedef state = @{ addr= uint8, ps= pstate }  
fun process (ch:int, s: &state) : void = let  
val sn = case [s.ps](http://s.ps) of  
| AtomicA () =\> let  
val \_ = case cast{char}(ch) of  
| ‘z’ =\> let  
val \_ = do\_something()  
in s.addr := s.addr; [s.ps](http://s.ps) :=  
NonAtomicA end  
| ‘T’ =\> let  
val mode = serial\_poll()  
val ns = if mode = 1 then AtomicA  
else AtomicB  
in s.addr := s.addr; [s.ps](http://s.ps) := ns  
end  
| \_ =\> let \_ in \_ end  
in \_ end  
| AtomicB () =\> let \_  
val \_ = case cast{char}(ch) of  
| ‘z’ =\> let  
val \_ = do\_something()  
in s.addr := s.addr; [s.ps](http://s.ps) :=  
NonAtomicB end  
| ‘T’ =\> let  
val mode = serial\_poll()  
val ns = if mode = 1 then AtomicA  
else AtomicB  
in s.addr := s.addr; [s.ps](http://s.ps) := ns  
end  
| \_ =\> let \_ in \_ end  
in \_ end  
| NonAtomicA () =\> let  
in \_ end  
| NonAtomicB () =\> let \_  
in \_ end

```
          | Hang () => _

```

in  
end

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [October 1, 2015, 10:11pm UTC](https://discourse.ats-lang.org/t/case-statement-wont-compile/811/2 "2015-10-01T22:11:19Z")

</div>

In ATS, pls use either case+ or case-; if you use case, the compiler  
currently always add a run-time catchall.On Oct 1, 2015 5:43 PM, “Mike Jones” [proc...@gmail.com](mailto:proc...@gmail.com) wrote:

> I had some code that worked, then after a change won’t compile, but I  
> don’t understand why.
> 
> The code that compiled and worked had three value constructors and a FSS  
> that switched states between two states, AtomicA and Atomic B. You can see  
> this i the code here:
> 
> datatype pstate =  
> | AtomicA of ()  
> | AtomicB of ()  
> | Hang of ()
> 
> typedef state = @{ addr= uint8, ps= pstate }  
> fun process (ch:int, s: &state) : void = let  
> val sn = case s.ps of  
> | AtomicA () =\> let  
> val \_ = case cast{char}(ch) of  
> | ‘z’ =\> let  
> val \_ = do\_something()  
> in s.addr := s.addr; s.ps :=  
> AtomicA end  
> | \_ =\> let \_ in \_ end  
> in \_ end  
> | AtomicB () =\> let \_  
> val \_ = case cast{char}(ch) of  
> | ‘z’ =\> let  
> val \_ = do\_something()  
> in s.addr := s.addr; s.ps :=  
> AtomicB end  
> | \_ =\> let \_ in \_ end  
> in \_ end
> 
> ```
> | Hang () => _
> 
> ```
> 
> in  
> \_  
> end
> 
> Then I added two constructors, and made the transitions more complex, as  
> the case for AtomicA can change to one of two states. Then it won’t compile  
> and gives the error:
> 
> undefined reference to `atsruntime\_handle\_unmatchedval’
> 
> The range of lines is the entire top self case statement.
> 
> I change the top level case from “case” to “case+” and it compiles.
> 
> Can anyone explain why this makes it compile?
> 
> Note that all cases are covered because they all have a “\_” pattern at the  
> bottom to match on.
> 
> datatype pstate =  
> | AtomicA of ()  
> | NonAtomicA of ()  
> | AtomicB of ()  
> | NonAtomicB of ()  
> | Hang of ()
> 
> typedef state = @{ addr= uint8, ps= pstate }  
> fun process (ch:int, s: &state) : void = let  
> val sn = case s.ps of  
> | AtomicA () =\> let  
> val \_ = case cast{char}(ch) of  
> | ‘z’ =\> let  
> val \_ = do\_something()  
> in s.addr := s.addr; s.ps :=  
> NonAtomicA end  
> | ‘T’ =\> let  
> val mode = serial\_poll()  
> val ns = if mode = 1 then  
> AtomicA else AtomicB  
> in s.addr := s.addr; s.ps := ns  
> end  
> | \_ =\> let \_ in \_ end  
> in \_ end  
> | AtomicB () =\> let \_  
> val \_ = case cast{char}(ch) of  
> | ‘z’ =\> let  
> val \_ = do\_something()  
> in s.addr := s.addr; s.ps :=  
> NonAtomicB end  
> | ‘T’ =\> let  
> val mode = serial\_poll()  
> val ns = if mode = 1 then  
> AtomicA else AtomicB  
> in s.addr := s.addr; s.ps := ns  
> end  
> | \_ =\> let \_ in \_ end  
> in \_ end  
> | NonAtomicA () =\> let  
> in \_ end  
> | NonAtomicB () =\> let \_  
> in \_ end
> 
> ```
> | Hang () => _
> 
> ```
> 
> in  
> \_  
> end
> 
> –  
> You received this message because you are subscribed to the Google Groups  
> “ats-lang-users” group.  
> To unsubscribe from this group and stop receiving emails from it, send an  
> email to [ats-lang-user...@googlegroups.com](mailto:ats-lang-user...@googlegroups.com).  
> To post to this group, send email to [ats-lan...@googlegroups.com](mailto:ats-lan...@googlegroups.com).  
> Visit this group at [http://groups.google.com/group/ats-lang-users](http://groups.google.com/group/ats-lang-users).  
> To view this discussion on the web visit  
> [https://groups.google.com/d/msgid/ats-lang-users/c87bd596-75a6-45b9-b63a-c3a65992c14a%40googlegroups.com](https://groups.google.com/d/msgid/ats-lang-users/c87bd596-75a6-45b9-b63a-c3a65992c14a%40googlegroups.com)  
> [https://groups.google.com/d/msgid/ats-lang-users/c87bd596-75a6-45b9-b63a-c3a65992c14a%40googlegroups.com?utm\_medium=email&utm\_source=footer](https://groups.google.com/d/msgid/ats-lang-users/c87bd596-75a6-45b9-b63a-c3a65992c14a%40googlegroups.com?utm_medium=email&utm_source=footer)  
> .
