The Crystal Programming Language Forum

Use !! to unwrap like swift

not_nil! is a bit long.

!! can not in title

I have not written much swift but the swift I have written unwrapping was everywhere. Part of that seemed like it was how the underlying libraries where designed.

I don’t know if this is a intentional from the crystal design teem but I feel like I unwrap less in crystal because of the api of the std lib.

If you want to get feedback on introducing some syntax I would open a github issue.

In Crystal you usually shouldn’t have to use not_nil!. Crystal’s type inference does a great job at ensuring non-nilable types when the value can’t be nil. But if it can be nil, you ought to handle that case explicitly.
Using not_nil! is in most cases considered a code smell. It can be useful sometimes for example when the the compiler can’t figure out an interdependency between different variables that ensures not-nil values. But these are typically quite rare cases. If you’re using not_nil! in your everyday code, chances are, you should reconsider either your declared types or your error handling.

not_nil! should definitely be handled with care, because it can lead to surprising breakages in your code, when you expect a value can’t be nil but what happens if it is?

By design, not_nil! is not very common and needs special attention. There is no reason to ease accessibility.

2 Likes

In the beginning we didn’t know what to use to turn something from T | Nil to just T and we introduced not_nil!. We said “we’ll eventually come up with something less ugly”. What happened is that not_nil! reads so bad and it’s quite long that it made us try to avoid it in our code as much as possible. In Swift it’s so easy to just add ! when you get a compile error that it doesn’t give you a proper chance to think about how to handle that case. Then we concluded that not_nil! being long and ugly was a good thing because people will try to avoid it :slight_smile:

4 Likes

Even #as T is better than not_nil!, because the error raised will give more information: cast from U to T failed instead of Nil assertion failed