Calling internal functions - foo::bar() ?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Calling internal functions - foo::bar() ?

Kostis Sagonas-3
"Thomas Lindgren" <thomasl_erlang> replied to my post:
 >
 > >  > Introducing :: may, as you say, still be a bad idea.
 > >
 > > Indeed it is.  A very bad one in fact.
 >
 > Given the prevalence of export_all all the way to
 > deployed code, there still seems to be a customer, er,
 > developer need for this sort of functionality :-)

Just in case some of my points were too implicit, let me make them
more explicit:

Most of us agree that "export_all" is a terrible kludge, but some
feel that is is occasionally helpful in developing/debugging.

However bad it may be, note that at least it has the property that
it allows the compiler to optimize internal functions in modules
that do NOT contain an "export_all".  This is something detectable
at compilation time (i.e., when the .beam file is generated) and
trivially also detectable by using "grep".

The BEAM/native code code compiler is thus allowed to say: "Aha, the
programmer has used an export_all in this module; I will punish her
by not performing any optimizations in that module, and will only
optimize the internal functions in the rest of her modules."

The latter is possible _because_ there is currently no construct to
call internal functions.

In the presence of a :: construct, no sophisticated optimizations
are possible to perform without having a fall-back mechanism.
This puts an unnecessarily big implementation effort to the compiler's
optimizer and significantly increases the size of the generated .beam
files.

Good that the OTP team opted against it.

Best,
Kostis



Reply | Threaded
Open this post in threaded view
|

Parse transformery (Was: Re: Calling internal functions - foo::bar() ?)

Luke Gorrie-3
Kostis Sagonas <kostis> writes:

> Just in case some of my points were too implicit, let me make them
> more explicit:

We agree that export_all is bad. What we disagree on is the relative
importance of troubleshooting tools vs. compiler optimization. This is
hardly surprising since one of us is troubleshooting running systems
all day and the other is developing compiler optimizations. :-)

I did my thing with a parse transform. My problem now is how to handle
'make' dependencies in the presence of parse transforms. (Anyone know?)

I can compile this module:

  -module(x).
  -compile({parse_transform,internal_exports}).

  a() -> working.
  z(X) -> {ok, X}.

and I can call its internal functions in the shell:

  5> x:a().
  working
  6> x:z(42).
  {ok,42}

but they are not really exported. The trick is based on the one that
Erik Stenman sent me when we had this thread years ago:

  7> x:'EXPORTER'().
  [{{a,0},#Fun<x.0.15689079>},{{z,1},#Fun<x.1.108540428>}]

i.e. the parse transform has synthesized an 'EXPORTER' function that
returns funs for everything.

Of course I have hacked the shell to support this interface (patch
below) but it can also be used in a more klunky way:

  8> internal_exports:apply(x, a, []).
  working

which might be bearable with this user_default function:

  iapply(M, F, A) -> internal_exports:apply(M, F, A).

but I'll stick with the customized shell for now.

The parse transform is lib/msc/src/internal_exports.erl in jungerl.

Cheers,
Luke

P.S. Good luck Mats on getting this adopted for AXD301. :-)

-------------- next part --------------
A non-text attachment was scrubbed...
Name: erl_eval.patch
Type: text/x-patch
Size: 1204 bytes
Desc: internal_exports patch to erl_eval.erl
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20050308/86c06ab4/attachment.bin>

Reply | Threaded
Open this post in threaded view
|

Parse transformery (Was: Re: Calling internal functions - foo::bar() ?)

Luke Gorrie-3
Luke Gorrie <luke> writes:

> I did my thing with a parse transform. My problem now is how to handle
> 'make' dependencies in the presence of parse transforms. (Anyone know?)

I found a nice way to globally enable this for files compiled on my
local machine:

 # This in ~/.bashrc:
 export ERL_COMPILER_OPTIONS='[debug_info,{parse_transform,internal_exports}]'
 % This in ~/.erlang:
 code:add_pathz("/where/the/parse/transform/module/is/ebin").




Reply | Threaded
Open this post in threaded view
|

Parse transformery (Was: Re: Calling internal functions - foo::bar() ?)

Mats Cronqvist (ÄL2/EAB)
In reply to this post by Luke Gorrie-3


Luke Gorrie wrote:

> Kostis Sagonas <kostis> writes:
>
>>Just in case some of my points were too implicit, let me make them
>>more explicit:
>
>
> We agree that export_all is bad. What we disagree on is the relative
> importance of troubleshooting tools vs. compiler optimization. This is
> hardly surprising since one of us is troubleshooting running systems
> all day and the other is developing compiler optimizations. :-)

   i was just going to comment to Kostis that for the AXD301, the choice between
a 5% compiler optimization and 5% better turnaround time on bug fixes is a
no-brainer (in favor of better debugging).
   alas, while i personally like the M::F shell-only proposal, i don't see it as
being very helpful in AXD301 development.
a) it's only really useful to the guy who wrote the code...
b) ...and the function is reasonably side-effect free
c) we already have the problem that the shell is abused on live nodes (by
non-developers)
   if i thought otherwise i'd be mail-bombing the OTP guys right now.

> The parse transform is lib/msc/src/internal_exports.erl in jungerl.
>
> Cheers,
> Luke
>
> P.S. Good luck Mats on getting this adopted for AXD301. :-)

   i'll just explain to the bosses that it's object-oriented and they'll give me
a raise :>


Reply | Threaded
Open this post in threaded view
|

Parse transformery (Was: Re: Calling internal functions - foo::bar() ?)

Luke Gorrie-3
In reply to this post by Luke Gorrie-3
Luke Gorrie <luke> writes:

> Of course I have hacked the shell to support this interface (patch
> below) but it can also be used in a more klunky way:

MY GOD I NEED TO LEARN TO PROGRAM.

> --- erl_eval.erl.orig 2005-03-08 01:40:58.000000000 +0100
> +++ erl_eval.erl 2005-03-08 02:20:00.000000000 +0100
> @@ -396,7 +396,32 @@
>  %% ExternalFuncHandler = {value,F} | none.
>  %% MF is a tuple {Module,Function} or a fun.
>  
> -do_apply(Func, As, Bs0, Ef, RBs) ->
> +do_apply({Mod,Func}, As, Bs0, Ef, RBs) ->
[ ... ]
> +    end.
> +
> +do_apply1(Func, As, Bs0, Ef, RBs) ->

You don't need to be a dializer to see that calling funs from my
erlang shell has been broken since march.

Updated erl_eval patch is attached in case someone is using the parse
transform. (I'm still stuck in R9B-0 land for the moment now.)

-------------- next part --------------
A non-text attachment was scrubbed...
Name: erl_eval.patch
Type: text/x-patch
Size: 1303 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20050923/d521940e/attachment.bin>