# Run time assertions and type reductions

**URL:** <https://forum.crystal-lang.org/t/run-time-assertions-and-type-reductions/4694>\
**Category:** Help & Support\
**Created:** [June 18, 2022, 12:19pm UTC](https://forum.crystal-lang.org/t/run-time-assertions-and-type-reductions/4694 "2022-06-18T12:19:48Z")\
**Posts on this page:** 1\
**Showing post:** 7

<div class="post-metadata">

**Author:** ![wolfgang371](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/wolfgang371/32/1665_2.png) [@wolfgang371](https://forum.crystal-lang.org/u/wolfgang371)\
**Post date:** [June 26, 2022, 7:42pm UTC](https://forum.crystal-lang.org/t/run-time-assertions-and-type-reductions/4694/7 "2022-06-26T19:42:04Z")

</div>

Now you’re mixing up compile time and runtime. This version of `assert` is supposed to check the invariant at runtime (opposed to [Generic compile time assertions](https://forum.crystal-lang.org/t/generic-compile-time-assertions/4690)).  
Nevertheless, it also reduced types on compile time, as `raise` does in the initial example.

Your last proposal doesn’t work for the initial example:

```crystal
# doesn't compile
macro assert(invariant)
  {% unless invariant %}
    raise("runtime_assert")
  {% end %}
end

# compiles
# macro assert(invariant)
# {% if invariant %}
# raise("runtime_assert") if !{{invariant}}
# {% else %}
# raise("runtime_assert")
# {% end %}
# end

def fn(arg : Bool|Int32)
    assert(!arg.is_a?(Bool))
    arg+42 # compile-time error in case of the first assert variant, assert doesn't reduce the type
end

a = [1,true]
p fn(a[0])

```

I’m not sure if the working version can be reduced.

---

_[View the full topic](https://forum.crystal-lang.org/t/run-time-assertions-and-type-reductions/4694)._
