The first problem with this is it leads to insanity. Remember those arguments developers had about style before we adopted auto-formatting? Those arguments will happen about what is and what isn't a distinct type.
But the main problem for me is the cost is too high for such little benefit. Understanding and maintaining a type system like that is hard. You are not going to eliminate all bugs. Wouldn't the effort be better spent on writing more tests? I feel like developers prefer creating more types over writing more tests because it's easier, though.
Some of these problems have good, practical solutions already:
> Good luck figuring all of that out from the following signature: > CompletionStage<String> x(String s, int i);
I agree, but you could just use good naming: `fetchAddress(postcode, housenumber)`
> functions with two or more arguments of the same type
Use keyword arguments, ie. `kwargs` in Python or pass an object in JS.
> UUIDs as method argument, a customer uuid is not the same as an order uuid.
This contradicts the Universal part of UUID. If they're not the same then why use UUID at all?
> using a List instead of a NonEmptyList when at least one element is expected.
I'm not sure why this is a problem. An empty list is a perfectly valid list. It strikes me that what you really wanted to pass was an object, not a list.