The problem with returning null is that you end up with an error in one part of the code causing an exception in a later part of the code.
Integer i = foo();
//Do a bunch of stuff
doSomething(i);
is much harder to debug, especially if doSomething() is documented that it is forbidden to call with a null. You now need to find where i came from, which can be non-trivial.
If instead you return Either<SomeError,Integer> you now can't call a function that hasn't contracted to either not unbox the value, or deal with the error. It's making the type signature match the documentation, which means that the compiler will help catch programmer error. I don't see how this can be anything but a good thing.
Integer i = foo(); //Do a bunch of stuff doSomething(i);
is much harder to debug, especially if doSomething() is documented that it is forbidden to call with a null. You now need to find where i came from, which can be non-trivial.
If instead you return Either<SomeError,Integer> you now can't call a function that hasn't contracted to either not unbox the value, or deal with the error. It's making the type signature match the documentation, which means that the compiler will help catch programmer error. I don't see how this can be anything but a good thing.