Thank you for your comment about primitive obsession. I did read the medium story below. You raise an astute point.
To avoid the problem of primitive obsession, I believe that we should have an Email class in your story’s example. The Email class should have validation behaviour. Then, we avoid any need for an extension function or a utility class which has a function accepting a String as an Email. As you correctly point out, we shouldn’t represent emails as strings.
I believe your story is reaching the wrong conclusion. If we accept that
fun String.validateEmail(): Boolean = …
is wrong, then it follows that
public static boolean validateEmail(String email) …
is also wrong, because the Kotlin resolves the extension function to byte code essentially as a static function. The extension function’s receiver becomes the first parameter of the method.
I believe that the story’s proper conclusion is that if
fun String.validateEmail: Boolean = …
is wrong because of primitive obsession reasons, then we need an Email class which has validation behaviour.