loading...

Make impossible states impossible - Kotlin edition

Pin-Sho Feng on March 16, 2020

Sometimes called "functional domain modelling", there are a bunch of articles and videos titled like that but I haven't found a Kotlin edition, so ... [Read Full]
markdown guide
 

That is a clever usage of interfaces!

I recently had to deal with a similar case while refactoring some legacy code.
My approach to create valid entities was achieved via factory functions. In a nutshell you can have a

fun UserName(value: String): UserName? {
    return if (value.isEmpty()) null else UserName(value)
}

which tricks the dev to think that is using a constructor but at the same time keeps everything valid and readable.

If you are interested I wrote a blog post here.

 

Interesting blog post, thanks! I like that increasingly more people are aware of this problem :)

As for the suggestion, I'd advise against doing it that way because it goes against the conventions:

  • Naming: function names should start with a lowercase letter, see here.
  • From outside it looks like a constructor and I wouldn't expect a constructor to return null.

My 2 cents.

 

Both arguments are valid. Especially the second one didn't even crossed my mind. Thank you!

 

Big fan of such (Functional) domain modelling.
What's your take on the Null vs Option vs Either?
From my perspective:

  • Null and Option have a similar semantics; they both can model the availability or absence of a value
  • Either can help you document the error cases in more detail to expose what is wrong and perhaps have decisions made based on that, or to report it back to the user.

My interest is in when to choose Null or Option. I'm facing the dilemma in Typescript; if I don't need the resolution of Either, shall I use Option or just keep it simple with Null...
That is ignoring for a moment that we also have undefined ;-)

In languages without good type support, null can be a real pain, but in Typescript and I suppose Kotlin, things are better. So I guess it just is a matter of null can make it more difficult to compose, yet easier to consume as you only need to assert, not unwrap like Option/Either.

 

I've had the exact same dilemma and for the moment my loosely-held conclusion is that Option is unnecessary in Kotlin. Perhaps if you use Arrow it provides syntax sugar with monad comprehensions but I wouldn't say that's a good enough reason to use it over built-in nullables.

The only case where I think using Option or Optional has an advantage is when your code needs to be used from Java and you want to keep null-safety. Would this apply to Typescript and Javascript?

 

Great article. However, I will say if you want first party support for unions it’s likely better to use a language that has unions like TypeScript.

 

I'd say that multiple reasons need to be evaluated before choosing one language or another :)

code of conduct - report abuse