the OO metaphor

Ulf Wiger <>
Wed Nov 29 11:00:10 CET 2000


On Tue, 28 Nov 2000, Vlad Dumitrescu wrote:

>The "thread thread" is very interesting, and talking about OO
>reminded me of an idea I got... I think it's not a very bad one, so
>I will share it with you, to see what you think.
>
>The OO methodology can be easily applied to Erlang, once one gets to
>ffel the pulse of the language. There is however one thing that is
>missing, and that I think it could be useful. That thing is
>inheritance.

I might then as well share something that I started hacking on
a few weeks ago. It seems to have come to a stop, so this might 
be a good time to see if there's any interest in continuing...

I called it system_erlang. I tried to address the following:

- my old idea of extending the receive statement to automatically 
  handle system messages

- API inheritance, resolved at module load time

- fast-path execution, inspired by work I've seen on forwarding 
  engines, the Erlang processor, and the new filtering mechanisms in
  OTP R7B (also Thomas Lingren's ongoing work.)

Comments are much appreciated.

/Uffe


%% Sample erlang module

-module(syserl).

-export([foo/0,
	 bar/0]).

%-import_directives(otp, [$extend_receive/1]).
%-export_to(Module, [Function/Arity]).
%-bounded_time([Function/Arity]).

%%% About system directives
%%% When building large complex erlang systems, one often wants to control
%%% the use of interfaces and seamlessly add support for system messages.
%%%
%%% Richard O'Keefe's suggestion of -export_to/2 is a good idea, e.g. 
%%% because it allows hiding of "internal" exports, and restricted use of 
%%% functions exported for a special purpose (e.g. application:set_env/3). 
%%%
%%% I'd also like to be able to inherit interfaces from another module: 
%%% an example is when writing a mnesia access module in order to redefine 
%%% only a few access functions in mnesia; today one must redefine them all, 
%%% even if the majority of functions will simply call the default mnesia
%%% function. This forces the maintainer of a mnesia access module to update 
%%% their module every time a new access function is added to mnesia - even 
%%% if this particular function is of no interest to the access module in 
%%% question.
%%%
%%% Redefining message reception is difficult to do seamlessly:
%%% - if it's done in a library module, there is no room for selective receive
%%% - if it's done via a macro, variable binding becomes a problem. Also one 
%%%   must implement all the sys.erl callbacks, which is error prone.
%%%
%%% My approach is to introduce system directives, allowing each module to 
%%% "enhance" keywords and inherit interfaces. In the example below, I have
%%% defined a keyword, system_receive, which can be used in place of 'receive'.
%%% It should be possible to also redefine 'receive', but most likely, the
%%% special feature of handling system messages would be used only in a few
%%% functions (the main event loop or certain states.)
%%% The interface inheritance could also mean that I wouldn't have to write
%%% the special sys.erl callback functions, which eliminates a source of 
%%% errors.
%%%
%%% These system directives look pretty much like normal erlang functions,
%%% (except for the illegal function names) but are callable only by the VM.
%%% For this, the compiler may have to insert some helper function to help
%%% the loader make the calls (e.g. $fast_path/2 needs to be called once for
%%% each function.)
%%%
%%% An issue to discuss is how/if to make a distinction between compiler 
%%% directives and system directives. For example, inheriting the interface
%%% of another module should be a system directive, in the sense that it 
%%% should be resolved at runtime - not compile-time. Enabling fast-path
%%% execution might be handled by the compiler, but this requires knowledge
%%% about other modules, if we are to allow inter-module calls in fast-path
%%% processing. Making it a system directive would probably imply some kind
%%% of JIT.

%%% System directives.
%%% So far, we define four system directives:
%%% - $extend_receive(MyReceiveKeyword) -> ...<receive pattern>....
%%%      This is used to define our own message reception semantics. The most
%%%      useful variant will be to 
%%% - $receive(), which is used in $extend_receive/1 to mark where the 
%%%                original receive clauses go.
%%%
%%% - $inherit_api(FromModule) -> all | [Exceptions].
%%%      This is used to include the exported functions of FromModule as 
%%%      part of the exported functions in this module.
%%%
%%% - $fast_path(Function, Arity) -> hard | {hard, ExitFunction} | soft | none.
%%%      This is used to identify functions that are candidates for fast-path
%%%      compilation. The return value specifies what should happen if 
%%%      fast-path execution fails (which could possibly be when it 
%%%      encounters a side-effect or a function of unknown complexity):
%%%      - 'hard' means simply exit;
%%%      - {hard, ExitFunction} means that ExitFunction should be called
%%%        (Example: a device processor performs fast-path analysis; failure
%%%        leads to the packet being sent to a (slow path) control processor)
%%%      - 'soft' means that fast-path failure triggers a slow-path 
%%%        (normal erlang) re-run
%%%      - 'none' means normal erlang - allowed for completeness only.

$extend_receive(system_receive) ->
   receive
      Msg when element(1, Msg) == system, size(Msg) == 6 ->
         sys:handle_system_messages(...);
      $receive()
   end.

$inherit_api(foo) ->
   %% inherit all exported functions from foo.erl, except foo:fooey/1, which
   %% is redefined in our module (runtime error if no such function is
   %% exported), and foo:buggy/0, which is not available through this module.
   %% syserl:buggy() will IOW cause exit({undef, _}).
   [{redefine, [fooey/1]},
    {exclude, [buggy/0]}];
$inherit_api(bar) ->
   %% no special instructions, i.e. inherit all exported functions from bar.erl
   all.



-- 
Ulf Wiger                                    tfn: +46  8 719 81 95
Senior System Architect                      mob: +46 70 519 81 95
Strategic Product & System Management    ATM Multiservice Networks
Data Backbone & Optical Services Division      Ericsson Telecom AB




More information about the erlang-questions mailing list