In most IDEs, you can simply mouseover the variable if you want to know. In addition, really, if you're working in an instance method, you should really know all the variables involved. If you have too many, or their names clash, then you need to refactor.
It's really quite redundant.
In terms of functional programming, what you and your colleague are discussing is point free style, more specifically eta reduction. Consider the following two assignments:
Predicate<Result> pred = result -> this.isResultInFuture(result);
Predicate<Result> pred = this::isResultInFuture;
These are operationally equivalent, and the first is called pointful style while the second is point free style. The term "point" refers to a named function argument (this comes from topology) which is missing in the latter case.
More generally, for all functions F, a wrapper lambda that takes all arguments given and passes them to F unchanged, then returns the result of F unchanged is identical to F itself. Removing the lambda and using F directly (going from the pointful style to the point-free style above) is called an eta reduction, a term that stems from lambda calculus.
There are point free expressions that are not created by eta reduction, the most classic example of which is function composition. Given a function from type A to type B and a function from type B to type C, we can compose them together into a function from type A to type C:
public static Function<A, C> compose(Function<A, B> first, Function<B, C> second) {
return (value) -> second(first(value));
}
Now suppose we have a method Result deriveResult(Foo foo)
. Since a Predicate is a Function, we can construct a new predicate that first calls deriveResult
and then tests the derived result:
Predicate<Foo> isFoosResultInFuture =
compose(this::deriveResult, this::isResultInFuture);
Although the implementation of compose
uses pointful style with lambdas, the use of compose to define isFoosResultInFuture
is point free because no arguments need to be mentioned.
Point free programming is also called tacit programming, and it can be a powerful tool to increase readability by removing pointless (pun intended) details from a function definition. Java 8 doesn't support point free programming nearly as thoroughly as more functional languages like Haskell do, but a good rule of thumb is to always perform eta-reduction. There's no need to use lambdas that have no different behavior from the functions they wrap.
Best Answer
I believe this is nothing but a matter of style - no "measure of readability" (which is always personal) can help you here.
So before I go any further, let me say this: Whatever the style choice, if you're working in a team, define a clear standard that the whole team must comply with, because if there is one thing that everyone can agree on that makes code less readable, is having to keep up with different style choices as you read it.
But now to the main subject:
self
,this
orme
, as present in many OO languages, are featured roughly for the following reasons:this.class
in Java;As with many other details that are abstracted away from us when we use OO languages (vtables, etc...),
self
could also be hidden, if it weren't for the reasons above.So my opinion is that you should only use it when necessary, as above. Of course, this idea only works well along with the practice of making small classes and methods; otherwise, both your local and global scopes are going to be so big that it will always be confusing, forcing the reader to jump up and down in the code, looking for the definitions. But I'm tempted to say, in these cases, that it is not the consistency of style that is going to save you.