[erlang-questions] some language changes

Kenneth Lundin kenneth.lundin@REDACTED
Thu May 31 13:56:23 CEST 2007


Just for information I can say that we in the OTP team have a clear stategy
not to use conditional compilation at all for Erlang code. At least
not for release builds. We tried that in the beginning but found that
it was a bad idea.
So, all Erlang code is unconditionally compiled for the release.
If that is not true it is a bug to be corrected.
For example different behaviour on different plattforms is always handled in
runtime with a call to os:type().
There might be complete modules which only are used on a specific platform.
This result in that all .beam files are the same for all plattforms
and this will
also be evident in the next open source release which will contain pre-built
.beam files.


On 5/31/07, ok <ok@REDACTED> wrote:
> On 31 May 2007, at 1:51 am, Mats Cronqvist wrote:
> [1. simplify the language]
> [2. replace the preprocessor]
> >  conditional compilation should (i think) be
> > disallowed (rarely used and utterly horrible).
> I have been saying "Delenda est preprocessor!" since it came out.
> I note, however, that there are 518 "-if[n]def(...)." occurrences
> in the R11B sources.
> Quite a lot of those are protection against multiple includes:
>         %% thingy_whatsit_gubbins.hrl
>         -ifndef(THINGY_WHATSIT_GUBBINS_HRL).
>         -define(THINGY_WHATSIT_GUBBINS_HRL, true).
>         ...
>         -endif.
> To my astonishment, some of the files that do this contain nothing else!
> The answer is simple:  they are produced by some kind of tool that
> emits -record declarations, and for these files there happened to be
> none.  Some use a _HRL suffix; some use a -MIB suffix.
> This usage accounts for 165 (32%) of the -ifs.  Either of two changes
> would eliminate them entirely.
> (a) -require(File_Name).
>      would resolve the File_Name just like -include(File_Name),
>      then check a list of included files.  If the file was in that
>      last, -require would do nothing, otherwise it would act just
>      like -include.  -include (and thus -require) would add the
>      resolved file name to the list.
> (b) Allow -define and -record declarations to be repeated, as long as
>      the repetitions are identical as token sequences.  (This is what
>      C does about #define.  6.10.3 "An identifier currently defined as
>      a macro ... shall not be redefined by another ... directive unless
>      the second definition is [the same kind, with the same arguments
>      if any] and the two replacement lists are identical.)
> There's a bunch of
>         -include("snmp_verbosity.hrl").
>         -ifndef(default_verbosity).
>         -define(default_verbosity, silence).
>         -endif.
> in lib/snmp/src/... , many of which never visibly mention
> default_verbosity again.  One wonders why this stuff isn't in
> snmp_verbosity.hrl itself.  2.5% of the -ifs have to do with
> SNMP verbosity; there has to be a better way to do this.
> Another 121 have "debug" in their name.
> Then there are at least 122 (24%) which are clearly Hipe-related.
> The use of -if to select data structures isn't really necessary.
> Instead of
>         %define(USE_TUPLES, true).
>         -define(USE_GBTREES, true).
>         -ifdef(USE_TUPLES).
>         new(N, V) ->
>             erlang:make_tuple(N, V).
>         ...
>         -endif.
>         -ifdef(USE_GBTREES).
>         new(N, V) ->
>             gb_trees:from_orddict(mklist(N, V)).
>         ...
>         -endif.
> one could write
>         Use = gb_trees.  % or tuples.
>         new(N, V) when Use =:= tuples ->
>             erlang:make_tuple(N, V);
>         new(N, V) when Use =:= gb_trees ->
>             gb_trees:from_orddict(mklist(N, V)).
>         ...
> This plus constant propagation, dead code elimination. and inlining
> does the trick.  Just allowing
>         <variable> = <constant expression>.
> at top level would go a long way towards eliminating -define.
> What this replacement cannot do, and what Hipe sometimes does,
> is
>         -ifdef(FOO).
>         -export([ick/1,ack/2,ugh/3]).
>         -endif.
> (not an actual example).
> Wait a bit.  Make that 141 (27%) in Hipe.  All the
>         -ifdef(notdef).
>         stuff
>         -endif.
> occurrences (19 of them) seem to be in there.  This amounts to
> commenting
> out code which is not currently in use but you're not quite ready to get
> rid of.  One problem with this is that code that is not compiled
> tends to
> suffer bit rot.  Other aspects of the code around it change so that when
> you decide that after all you DO want it back, it tends to have become
> unusable.  One could imagine a -moribund directive which would cause
> the following declaration to be syntax checked but discarded from the
> AST output.
> Prolog has a rather nice feature.  When you are reading terms from a
> file, the end of the file is indicated by returning the term
> 'end_of_file'.  So you can cause the compiler to stop early in a file
> by explicitly writing
>         end_of_file.
> So I tended to put test code and moribund code and big explanatory
> comments after an end_of_file, making it trivial to move them back
> where the compiler would see them if I wanted it to.  If you want to
> allow module definitions in the shell, you are going to want an -end
> directive there.  An -end directive is particularly nice for letting
> you put lots of commentary and examples and stuff in a file where
> people can see it, but where the compiler won't spend ANY time looking,
> unlike ordinary comments.
> That leaves about 76 (15%) of -ifs unexamined, and it's time I stopped.
> [3. Replace type guards by ::constraints on variables in patterns]
> Some IBM mainframe Prolog (was it VM Prolog?) did this, using infix
> $ rather than infix ::.  I've seen it in another language whose name
> I unfortunately forget.  However,
>   (a) This proposal makes the language more complicated.
>   (b) It makes some code more readable, but it makes other code
>       less readable.
>   (c) You STILL need type guards when there is a call to element,
>       hd, or tl in a guard, e.g.,
>         f(N, T) when is_pid(element(N, T)) -> ...
>   (d) You STILL need type guards when a guard is disjunctive, e.g.,
>         f(X) when is_record(X, update) ; is_record(X, delete) -> ...
> The Variable::type feature could be handled by source-to-source
> translation; the one case where this wouldn't be trivial is
> Pattern = Expression.
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions

More information about the erlang-questions mailing list