[erlang-questions] Is -extends() used in any projects?

Richard O'Keefe ok@REDACTED
Wed Jan 23 02:09:56 CET 2013


On 22/01/2013, at 7:44 PM, Björn Gustavsson wrote:

> -extends() was mentioned when we first talked
> about removing parameterized modules, so we
> assumed that we needed to emulate -extends()
> as well as parameterized modules.
> 
> It seems to be a good time to ask the question:
> 
> Is -extends() used by real projects? Do we really
> need to emulate it?
> 
> BTW, -extends() is described here:
> 
>   http://www.erlang.se/euc/07/papers/1700Carlsson.pdf

I believe that the design described there takes a wrong
step on the very first non-title slide:

	All function calls to new_module:f(...)
	will be redirected to old_module:f(...)
	if f is *NOT* exported from new_module.

I think that the rule "you may call m:f/n from
another module if and only if m explicitly
exports f/n" is an excellent rule.

It means that if you want to know what are the things
in module m, the information is right there in the
source code and the beam and if it is loaded,
module_info gives it to you.

With the design described in those slides, YOU NEVER
KNOW WHAT THE INTERFACE OF A MODULE (that has an
-extends in it) IS.

If you *don't* break the module-interfaces-are-knowable
rule, you get a different design which is entirely
compile-time (and thus faster):

If f/n is -exported
and f/n is not defined
and there is an -extends(m)
then generate a glue definition
	f(A1,...,An) -> m:f(A1, ..., An).

It's simple.
The full interface of a module remains discoverable.

And it's *faster*, because the current design
requires the lack of a definition to be detected at
run time, a trap out to a special handler (with the
arguments packaged into a data structure), time to
figure out what was undefined, the arguments have to
be unpacked again, and finally what would have been
the body of the glue definition is executed.
To quote Jayne, "where does that get to be fun?"

I once wrote a paper that I couldn't get published.
It described an object oriented extension to
Intercal, and it was as deliberately perverse as
plain Intercal.

This particular attempt to turn Erlang into an OO
language reminds me very much of that paper, only
it isn't funny when it's real.

I've built a Smalltalk implementation.  Now Smalltalk
was originally a single-inheritance language, and its
dynamic typing means that there are fewer constraints
on what you can do that way than there are in typical
typed OO languages.  Even so, there is rather more
code duplication than I am happy with, and it may be
this year that I finally add mixins.  (Or it may not.
There are enough other things to worry about.)  Why
mention that here?

Because the way -extends is presented in that paper
means that it can only support single inheritance.
(Since the ability to determine a module's full
interface has been destroyed, it cannot handle
	-extends(p).
	-extends(q).
by checking which of p, q defines f/n.)  And that's
an unjustified limitation.

Change it slightly.  Instead of -extends, use

	-export_from(Other_Module, Export_List).

That's just a handy abbreviation form.
	-export_from(m, [...,f/n,...]).
means
	f(A1, ..., An) -> m:f(A1, ..., An).

And now you have multiple inheritance.
And you have better compile-time checking:  things
are not re-exported *implicitly*, so if an
-exported function is not defined in *this* module,
that's still an error.

And the good part is that because a module's full
interface is discoverable, you can point your text
editor at a .beam file and say "generate me a
-export_from directive from _that_."  (Which should
be done by calling a little command-line tool:
generating an -export_from directive doubles very
nicely as a way for a human to find out what a module
exports without having to read the source code, which
they might not have anyway.)


a little command-line 


More information about the erlang-questions mailing list