[erlang-questions] Why we need a -module() attribute?

Richard A. O'Keefe ok@REDACTED
Fri Feb 19 05:30:44 CET 2016



On 17/02/16 10:45 pm, Konstantin Vsochanov wrote
> I’m working with Erlang for two years now and enjoy every day of using
> it. However, there are some strange  features I’m wondering about. One
> of them -module() attribute.

I've never really thought of it as an attribute, but I see from
http://erlang.org/doc/apps/erts/absform.html that you are correct to 
call it so.
>   The module name is strictly defined by the name of the .erl file.
The meaning of a module is defined by its *contents*.
More precisely, by the abstract syntax tree of the contents.
You can use http://erlang.org/doc/man/merl.html#compile-1
merl:compile(Code) to compile an Erlang module that never
was in a file, so *couldn't* have its name defined by the file name.

Following the example of the Juice compiler for Oberon,
we see that Erlang ASTs could compress very nicely.
We could imagine a version of Erlang working by pulling
compressed ASTs out of a CDB file.

One crucial point is that we cannot rely on file names for modules
because we cannot rely on file names, period.
For example, my department provides me with a desktop Mac and
a laptop Mac.  On the desktop machine, time_of_day.erl and
Time_Of_Day.erl are *different* file names; on the laptop they
are the *same* file name.  (I have actually been bitten by this,
though not yet with an Erlang module.)  Erlang as such does not
have any reason why there couldn't be a module named \

In fact, this works.
m% cat \\.erl
-module('\\').
-export(['div'/0]).
'div'() -> quotient.
m% erlc \\.erl
m% file \\*
\.beam: Erlang BEAM file
\.erl:  ASCII text
m% erl
1> l('\\').
{module,'\\'}
2>  '\\':'div'().
quotient

I don't advise you to try porting this file to Windows...

m% cat >A.erl
-module(a).
-export([b/0]).
b() -> c.
m% wc a.erl
m% wc a.erl
        3       5      38 a.erl
m% ls -li A.erl a.erl
72869017 -rw-r--r--  1 ok  wheel  38 19 Feb 16:42 A.erl
72869017 -rw-r--r--  1 ok  wheel  38 19 Feb 16:42 a.erl
m% erl
1> c('A').
A.beam: Module name 'a' does not match file name 'A'
error
2> c('a').
{ok,a}

You have no idea how confusing it is for the compiler to reject
a file when given the name it was created under, but to accept
the same file under an intrinsic alias.  *Especially* as when
typing file names on a case-ignoring file system, you tend to
get a bit sloppy with the shift key.

Frankly, I think that relying on file names is a system-level design
bug in Erlang.  It would be better to use something like OASIS
catalogues so that there were NO unpleasant interactions between
Erlang module names and file names:
  - no reserved characters (/. \)
  - no case problems
  - no problems with conflicts between the encoding of the contents
    of an Erlang module and the encoding assumed by the file system
  - no problems with Erlang module name length having to conform
    to the UNKNOWABLE file name limit of some future use

Aren't these problems with C too?  Not so much, because C doesn't
*have* module names (and C++ namespaces are  *not* tied to file
names).  Even so, having been burned a few times, so I have a little
AWK script:

#!/bin/awk -f
# Scan the current directory for file names differing only in case,
# which will cause problems porting to Mac OS X and Windows.

BEGIN {
     while (("ls" | getline original) > 0) {
         lower = tolower(original)
         tally[lower]++
         list[lower] = list[lower] " " original
     }
     close("ls")
     for (lower in tally) if (tally[lower] > 1) {
         print substr(list[lower], 2)
     }
}


| You can’t change module name with -module() attribute. But the the 
-module()
| attribute is mandatory. Why? Why we need -module() attribute at all?

> Maybe we can make -module() optional in next Erlang release?
NO!

You want to throw away the safe thing and keep the dangerous thing.
The -module declaration is the ONLY way have to tell that moving files
from one operating system to another HASN'T mangled them to breaking point.
>   So we don’t
> need to repeat file name in first string of every .erl file. Or maybe I
> miss something important?

Why would repeating the file name be a problem?
I have things set up in my text editor so that Meta-[-% inserts a 
standard header
(based on the file name).  The external file name this is based on has 
templates
that are easy enough to modify,  I get

%   File   : foobar.erl
%   Author : Richard A. O'Keefe
%   Updated: %G%
%   Purpose:

-module(foobar).

-export([
  ]).

To *not* repeat the module name, I would have to do EXTRA work.

Long term, we ought to be decoupling Erlang module names (and include files
etc) from file names entirely.  Some day someone will do

     % erlc grasp

and that will fetch the source code (compressed) from a repository over 
https
and produce a grasp.beam locally, plus a catalogue entry saying that module
'Grasp' is in 'grasp.beam'.

Until the happy day when field system weirdness can no longer harm us,
we MUST preserve -module as a safety measure.




More information about the erlang-questions mailing list