[erlang-questions] Overriding built-in functions in a module
Richard O'Keefe
ok@REDACTED
Fri Jun 11 01:58:46 CEST 2010
On Jun 10, 2010, at 1:40 AM, Raimo Niskanen wrote:
> I might argue that since it is a call to an exported function it
> must be to
> some *other* function, not the local with the same name.
Why? Suppose we have a module
-module(foo).
-export([bar/1]).
bar(N) when N > 0 -> ?MODULE:bar(N-1);
bar(0) -> 'DONG!'.
In what sense is the call to ?MODULE:bar/1 a call to some *other*
function than the bar/1 here before us?
It is often an excellent thing to write a self-tail-call as a remote
call so that the module can be replaced and the function switch over
to the new version. However, the vast majority of such calls will
NOT arrive at a different version, and it seems absurd to describe such
calls as calls "to some *other* function". How can it be a call to
a function other than the function it immediately calls?
> I am just used to the "not used" in this context meaning that if the
> function
> is removed the only thing that will happen is that the module gets
> smaller,
> or more correctly as you said: "no exported function directly or
> indirectly
> mentions f/n".
>
> "not used" is sloppier but shorter.
Other people are not used to that meaning. Since we have agreement
that '"not used" is sloppier', the only remaining questions are when
to replace it with something that isn't sloppy and what that should
be.
Another example.
-module(foo).
-export([h/1]).
f() -> 'F'.
g() -> 'G'.
i(X, X) -> f();
i(_, _) -> g().
h(X) -> i(X, X).
There is no possible execution path on which g/0 will be called.
The compiler is silent about this. Manually unfold the call to
i/2:
h(X) when X =:= X -> f();
h(_) -> g().
and the compiler warns that the second clause of h/1 can never
be used, but it still doesn't warn that g/0 can't be called.
Change it to
h(X) when is_list([X]) -> f();
h(_) -> g().
and there are no warnings at all. Change it to
h(_) -> f();
h(_) -> g().
and the compiler rightly warns about a clause that cannot match
and still fails to warn that g/1 cannot be reached. On the other
hand, introduce a syntax error in the first clause (but not the
second):
h(_) -> f);
h(_) -> g().
and now the compiler *does* warn that g/0 is unused, even though
there's an error-free clause right there calling it. YMMV but for
me this is the usual reason for such warnings.
I was wrong above. There -is- another question. What is the
purpose of this message? Is that purpose better served by
counting paths through unmatchable clauses or by discarding
such paths? Is that purpose well served by reporting this
'problem' when the compiler knows that it has not been able
to inspect all the possibly relevant code because of a syntax
error?
OK, it's a minor point and time I shut up, but bogus 'unused'
warnings have irritated me for a long time.
The Erlang compiler cannot be expected to solve the Halting Problem,
and I don't expect that.
More information about the erlang-questions
mailing list