From 634dd378030292abeec98e7f332e57c5d36e13ef Mon Sep 17 00:00:00 2001
From: Patrik Nyblom In the second form of function calls,
If
handle(Msg, State)
spawn(m, init, [])
@@ -238,16 +242,85 @@ Fun2([1,2], [3,4])
fun lists:append/2([1,2], [3,4])
=> [1,2,3,4]
- To avoid possible ambiguities, the fully qualified function - name must be used when calling a function with the same name as - a BIF, and the compiler does not allow defining a function with - the same name as an explicitly imported function.
+Note that when calling a local function, there is a difference
- between using the implicitly or fully qualified function name, as
- the latter always refers to the latest version of the module. See
-
See also the chapter about
If a local function has the same name as an auto-imported BIF,
+ the semantics is that implicitly qualified function calls are
+ directed to the locally defined function, not to the BIF. To avoid
+ confusion, there is a compiler directive available,
+
Before OTP R14A (ERTS version 5.8), an implicitly + qualified function call to a function having the same name as an + auto-imported BIF always resulted in the BIF being called. In + newer versions of the compiler the local function is instead + called. The change is there to avoid that future additions to the + set of auto-imported BIFs does not silently change the behavior + of old code.
+ +However, to avoid that old (pre R14) code changed it's + behavior when compiled with OTP version R14A or later, the + following restriction applies: If you override the name of a BIF + that was auto-imported in OTP versions prior to R14A (ERTS version + 5.8) and have an implicitly qualified call to that function in + your code, you either need to explicitly remove the auto-import + using a compiler directive, or replace the call with a fully + qualified function call, otherwise you will get a compilation + error. See example below:
+-export([length/1,f/1]).
+
+-compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported
+
+length([]) ->
+ 0;
+length([H|T]) ->
+ 1 + length(T). %% Calls the local funtion length/1
+
+f(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1,
+ %% which is allowed in guards
+ long.
+
+ The same logic applies to explicitly imported functions from + other modules as to locally defined functions. To both import a + function from another module and have the function declared in the + module at the same time is not allowed.
+ +
+-export([f/1]).
+
+-compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported
+
+-import(mod,[length/1]).
+
+f(X) when erlang:length(X) > 33 -> %% Calls erlang:lenght/1,
+ %% which is allowed in guards
+
+ erlang:length(X); %% Explicit call to erlang:length in body
+
+f(X) ->
+ length(X). %% mod:length/1 is called
+
+
+ For auto-imported BIFs added to Erlang in release R14A and thereafter,
+ overriding the name with a local function or explicit import is always
+ allowed. However, if the