[eeps] EEP for export_to

Raimo Niskanen raimo+eeps@REDACTED
Fri Aug 10 14:13:00 CEST 2007


I am resending this EEP for the archives, that just
recently started to work.

-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB
-------------- next part --------------
EEP: 5
Title: More Versatile Encapsulation with export_to
Version: $Revision: 18 $
Last-Modified: $Date: 2007-08-10 14:05:57 +0200 (Fri, 10 Aug 2007) $
Author: Per Gustafsson
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 10-Aug-2007
Erlang-Version: R12B-0
Post-History: 

Abstract
========

This EEP describes a new directive called export_to which allows a
module to specify exactly which other modules that can call a function
defined in the module. This provides a very fine grained primitive for
encapsulation. Allowing the programmer to control more directly how
his code should be used.

This is an idea originally proposed by Richard O'Keefe. 

Specification
=============

This is the syntax for the export_to directive:

``-export_to(m,[f/a])``

where `f` is the name of a function of arity `a` and `m` is a
module. (Perhaps we should allow a list of modules)

This means that the function f/a can be called from the module
m. Whether the call is a static call, dynamic call or an apply should
not matter.

In addition these functions should act as exported functions to the
rest of the world i.e. calls to these functions should always be to
the latest version of the function.

Motivation
==========

The module in Erlang have several roles. It is the unit of compilation
and code reloading. It is also the unit of encapsulation, because the
only way to hide a function from being called by any other function is
to make it a local function in a module. The module also defines a
separate namespace for functions. This wealth of roles for the module
makes it difficult to structure erlang applications in a way that
makes them well encapsulated while keeping modules small and focused.

Most applications written in Erlang consists of several smaller
modules, and though the application has a public API which is a subset
of the exported functions of the modules, exactly which functions that
are part of the public API can only be specified in comments or
documentation since functions are either exported so that anyone can
call them, or not exported meaning that they can only be called inside
the module, but sometimes we want to have more control than this
e.g. this function should only be called from other modules in this
application, or this function should only be called from the shell.

The export_to directive gives the programmer the possibility to
express such restrictions that the runtime system then enforces. It
should be noted that the export_to directive is not meant to replace
the export directive, but to be an alternative in the case when the
programmer knows all possible collaborators.

Rationale 
=========

There are some choices in designing the export_to syntax for example
should m be allowed to be a list of modules or should we have an
export_to list where each entry is a module, function/arity pair. One
reason to use the suggested syntax is that it reads pretty easily as:

export to module m this list of functions [f/a]

Another issue is whether we should have some syntactic sugar for
specifying common export patterns e.g. exporting a set of functions to
all the modules in an application or exporting a function in order to
make it possible to apply the function or to make it possible to
update the code of the function.

Discussions about such changes is outside the scope of this EEP, we
only note that the export_to directive makes a good building block for
creating such extensions without having to change the Erlang runtime.

  .. Other languages that have something like this? 

Backwards Compatibility
=======================

Adding an export_to directive should be totally backwards
compatible. Since writing such a directive now causes a syntax error
since it is not a legal attribute.

Implementation
==============

This feature has not been implemented yet, but here are some goals
that we think the implementation should fulfill:

* Ordinary static calls to an export_to function should cost the same
  as calls to other exported functions

* The performance of other calls should not be affected by the
  introduction of export_to calls

This can be archived by putting most of the machinery to handle this
feature in to the loader and only use dynamic checks for dynamic
calls.


More information about the eeps mailing list