[erlang-questions] I need to call unexported functions from the erlang shell

ok ok@REDACTED
Fri Jun 8 02:33:07 CEST 2007


Luke Gorrie wants to be able to poke around in modules deployed at
customer sites without resorting to parse transforms or -compile 
(export_all).

There is a problem here.  When you compile a file, you would like to
do things like eliminating dead code, especially after inlining.  But
if you eliminate dead code, it isn't _there_ when you want to call it
from the shell.  I have no idea whether the current Erlang compiler
eliminates dead code or not, but it's clearly something we would like
compilers to be able to do, especially for automatically generated  
source
code.

There's another problem.  Suppose you have a function which is not
exported, and the compiler notices that every call to it within the
module has some property.  (An argument might have a particular type,
for example.)  The compiler is entirely within its rights to compile
that function under the assumption that this property holds.  But then
if you call it from the shell and the property does not hold...

I suggest that Luke Gorrie's needs could best be served by

1. Providing another option, -compile(preserve_all), telling the
    compiler (and any future compiler) to preserve all functions,
    including ones that are neither called nor exported.  It also
    directs the compiler to preserve the most general interface for
    each function.  (A compiler that notices that some useful
    property is true at each call within the module may generate
    a specialised version of the function, but must still retain
    the original.)

    It might be appropriate to provide a directive
    -preserve([F1/N1, ..., Fk/Nk]) so that selected functions could
    be offered for debugging without exposing everything; we would
    then have preserve_all:preserve::export_all:export.

2. Providing an always-exported function '%preserved'/2.  For each
    preserved function (including exported functions) F/N, have
        '%preserved'(F, {X1,...,Xn}) -> F(X1, ..., Xn);
    so that the equivalent of mod::foo(X, Y) would be
	mod:'%preserved'(foo, {X,Y}).
    This would make calls to preserved functions possible anywhere,
    but easy nowhere.  Not something to be done lightly.

3. Providing an abbreviated syntax in the shell only:
	Mod::Fn(E1, ..., En) ==> Mod::'%preserve'(Fn, {E1,...,En})





More information about the erlang-questions mailing list