[erlang-questions] Defining static functions in abstract modules
Hynek Vychodil
vychodil.hynek@REDACTED
Wed Apr 9 11:20:54 CEST 2008
UGH, static functions? Where is benefit to do it? What matter? I don't
understand.
On Wed, Apr 9, 2008 at 11:04 AM, Matthew Dempsky <matthew@REDACTED>
wrote:
> It would be nice to be able to define arbitrary static functions
> within an abstract module. Right now you can kludge around this by
> exploiting that local functions named 'new' are always static and
> write something like
>
> new(incr, X) -> X + 1.
>
> but it would be nicer to just write
>
> -static([incr/1]).
> incr(X) -> X + 1.
>
> Below is a very rudimentary patch that adds support for this syntax.
> It's basically only enough to compile and run very simple test cases
> and to demonstrate that implementing this does not seem too difficult.
> (One problem I'm already aware of is that a static function foo/1 and
> an instance function foo/0 silently collide without any warning... so
> don't do that. ;-))
>
> Another option would be to make the attribute statement just
> "-static([incr])." and then all incr functions are defined static, but
> that seems unnecessarily limiting.
>
> If the long-term goal is to have separate namespaces for static and
> instance functions (e.g., so (Mod:new(...)):module_info() works and
> returns something meaningful for the module instance), then maybe a
> syntax that actually decorates individual function definitions would
> be better?
>
> Are there any plans on adding static functions in a future release?
>
>
> --- stdlib/src/erl_parse.yrl.orig 2007-11-27 07:57:32.000000000
> -0800
> +++ stdlib/src/erl_parse.yrl 2008-04-09 01:25:31.000000000 -0700
> @@ -627,6 +627,12 @@
> {attribute,La,export,farity_list(ExpList)};
> _Other -> error_bad_decl(La, export)
> end;
> +build_attribute({atom,La,static}, Val) ->
> + case Val of
> + [ExpList] ->
> + {attribute,La,static,farity_list(ExpList)};
> + _Other -> error_bad_decl(La, static)
> + end;
> build_attribute({atom,La,import}, Val) ->
> case Val of
> [Name] ->
> --- compiler/src/sys_pre_expand.erl.orig 2008-02-05
> 05:37:09.000000000 -0800
> +++ compiler/src/sys_pre_expand.erl 2008-04-09 01:26:06.000000000
> -0700
> @@ -38,6 +38,7 @@
> parameters=undefined, %Module parameters
> package="", %Module package
> exports=[], %Exports
> + statics=[], %Statics
> imports=[], %Imports
> mod_imports, %Module Imports
> compile=[], %Compile flags
> @@ -109,6 +110,7 @@
> end,
> {Fs1,Xs,Ds} = sys_expand_pmod:forms(Fs0, Ps,
> St0#expand.exports,
> + St0#expand.statics,
> St0#expand.defined),
> St1 = St0#expand{exports=Xs, defined=Ds},
> {Fs2,St2} = add_instance(Ps, Fs1, St1),
> @@ -220,6 +222,8 @@
> package = packages:strip_last(M)};
> attribute(export, Es, St) ->
> St#expand{exports=union(from_list(Es), St#expand.exports)};
> +attribute(static, Ss, St) ->
> + St#expand{statics=union(from_list(Ss), St#expand.statics)};
> attribute(import, Is, St) ->
> import(Is, St);
> attribute(compile, C, St) when is_list(C) ->
> --- compiler/src/sys_expand_pmod.erl.orig 2008-02-05
> 05:38:12.000000000 -0800
> +++ compiler/src/sys_expand_pmod.erl 2008-04-09 01:32:36.000000000
> -0700
> @@ -25,18 +25,19 @@
> %% and 'exports'. The automatic 'new/N' function is neither added to the
> %% definitions nor to the 'exports'/'defines' lists yet.
>
> --export([forms/4]).
> +-export([forms/5]).
>
> --record(pmod, {parameters, exports, defined, predef}).
> +-record(pmod, {parameters, exports, statics, defined, predef}).
>
> %% TODO: more abstract handling of predefined/static functions.
>
> -forms(Fs0, Ps, Es0, Ds0) ->
> +forms(Fs0, Ps, Es0, Ss0, Ds0) ->
> PreDef = [{module_info,0},{module_info,1}],
> - forms(Fs0, Ps, Es0, Ds0, PreDef).
> + forms(Fs0, Ps, Es0, Ss0, Ds0, PreDef).
>
> -forms(Fs0, Ps, Es0, Ds0, PreDef) ->
> - St0 = #pmod{parameters=Ps,exports=Es0,defined=Ds0, predef=PreDef},
> +forms(Fs0, Ps, Es0, Ss0, Ds0, PreDef) ->
> + St0 = #pmod{parameters=Ps,exports=Es0,statics=Ss0,defined=Ds0,
> + predef=PreDef},
> {Fs1, St1} = forms(Fs0, St0),
> Es1 = update_function_names(Es0, St1),
> Ds1 = update_function_names(Ds0, St1),
> @@ -50,15 +51,22 @@
> [update_function_name(E, St) || E <- Es].
>
> update_function_name(E={F,A}, St) when F =/= new ->
> - case ordsets:is_element(E, St#pmod.predef) of
> + case ordsets:is_element(E, St#pmod.predef) orelse
> + ordsets:is_element(E, St#pmod.statics) of
> true -> E;
> false -> {F, A + 1}
> end;
> update_function_name(E, _St) ->
> E.
>
> -update_forms([{function,L,N,A,Cs}|Fs],St) when N =/= new ->
> - [{function,L,N,A+1,Cs}|update_forms(Fs,St)];
> +update_forms([F0={function,L,N,A,Cs}|Fs],St) when N =/= new ->
> + F = case ordsets:is_element({N,A}, St#pmod.statics) of
> + true ->
> + F0;
> + false ->
> + {function,L,N,A+1,Cs}
> + end,
> + [F|update_forms(Fs,St)];
> update_forms([F|Fs],St) ->
> [F|update_forms(Fs,St)];
> update_forms([],_St) ->
> @@ -74,9 +82,14 @@
> {[], St0}.
>
> %% Only function definitions are of interest here. State is not updated.
> -form({function,Line,Name0,Arity0,Clauses0},St) when Name0 =/= new ->
> - {Name,Arity,Clauses} = function(Name0, Arity0, Clauses0, St),
> - {{function,Line,Name,Arity,Clauses},St};
> +form(F = {function,Line,Name0,Arity0,Clauses0},St) when Name0 =/= new ->
> + case ordsets:is_element({Name0, Arity0}, St#pmod.statics) of
> + true ->
> + {F,St};
> + false ->
> + {Name,Arity,Clauses} = function(Name0, Arity0, Clauses0, St),
> + {{function,Line,Name,Arity,Clauses},St}
> + end;
> %% Pass anything else through
> form(F,St) -> {F,St}.
>
> @@ -362,7 +375,13 @@
> expr({call,Lc,{atom,Lf,F},As0},St) ->
> %% Local function call - needs THIS parameter.
> As1 = expr_list(As0,St),
> - {call,Lc,{atom,Lf,F},As1 ++ [{var,0,'THIS'}]};
> + As2 = case ordsets:is_element({F, length(As1)}, St#pmod.statics) of
> + true ->
> + As1;
> + false ->
> + As1 ++ [{var,0,'THIS'}]
> + end,
> + {call,Lc,{atom,Lf,F},As2};
> expr({call,Line,F0,As0},St) ->
> %% Other function call
> F1 = expr(F0,St),
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions
>
--
--Hynek (Pichi) Vychodil
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20080409/35a8c811/attachment.htm>
More information about the erlang-questions
mailing list