Proposed change to libraries

Ulf Wiger (AL/EAB) ulf.wiger@REDACTED
Mon Feb 7 14:46:53 CET 2005


Kostis wrote:
> Besides checking that M and F are atoms, there needs to be a 
> check that the {M,F} is a valid fun object and its arity is 1
> (note the is_fun_arity new guard that is required in the second
> clause -- I wrote it as a comment but it really needs to be
> introduced in the language for the type inference
> algorithm to infer that the F in the first and the second 
> clause are of the same type).

Fine, but that should not be an inner loop check.

BTW, can is_fun_arity() really be a guard function?
With on-demand code loading, is_fun_arity can only
say whether a given function has the right arity if
it's already loaded - otherwise, it must fail - or 
the guard check potentially hang while the considerable
side effect of loading the module into memory is 
executed. I assume that this will not be allowed.

This would mean that lists:map/2 could fail even if 
the function {M,F} exists and has the right arity,
which would seem to violate Joe's Principle of Least
Astonishment.

Given that {M,F} must point to an exported function,
the BIF erlang:function_exported/3 seems to do pretty
much what you're asking for, except for a few oddities:

Eshell V5.4.3  (abort with ^G)
1> lists:map({erlang,abs},[-2,-1,0,1,2,3]).
[2,1,0,1,2,3]
2> erlang:function_exported(erlang,abs,1).
false
3> 

The documentation says the following:

"erlang:function_exported(Module, Function, Arity)

Returns true if the module Module is loaded and contains
an exported function Function/Arity; otherwise false. 

Returns false for any BIF (functions implemented in C 
rather than in Erlang). 

This function is retained mainly for backwards 
compatibility. 
It is not clear why you really would want to use it."


Note that this function is not allowed in guards.

PS
4> erlang:function_exported(erlang,send_nosuspend,3).
true
4> erlang:function_exported(erlang,send_nosuspend,3).
true
5> erlang:function_exported(ets,insert,2).           
false
6> erlang:function_exported(ets,tab2list,1).
true
7> erlang:function_exported(lists,append,2).
true
8> erlang:function_exported(erlang,yield,0).
true

The rule of returning 'false' for BIFs pretty much makes
this BIF unusable for practical purposes. In the examples
above, it's not even enough to look into the source code
to predict what this function will return. The Erlang source
for erlang:yield() looks like this:

yield() ->
   erlang:yield().

Go figure.  (:

/Uffe



More information about the erlang-questions mailing list