[erlang-questions] Third draft of EEP 44 - Additional preprocessor directives

Richard A. O'Keefe <>
Fri Oct 23 01:56:22 CEST 2015


I do hope this isn't the final draft.

(1) "OTP_RELEASE can infer information"

    What a clever little macro that must be.
    Statements IMPLY, people INFER.
    OTP_RELEASE can *IMPLY* something but never INFER anything.

(2) "As an hypothetical"

    "an" here must be "a".  If the h in "hypothetical" were
    silent, "an" would be appropriate.  But it isn't, and it isn't.

(3) It's the semantics.
    I hope you understand that I'm not quarrelling with the
    set of new built-in functions or their intended use or
    anything like that.  The set can always   extended later.
    My problem is that I still do not know WHAT THESE MEAN.

    There is a general problem that if I run the preprocessor
    at time T in context C, save the AST, and then finish the
    compilation at time T' in context C', the result that I
    get will not, in general, be the result I *would* have got
    at T in C.

    is_deprecated/3 : How do we know whether the compiler would
    have generated a warning or not?  If the compiler has been
    asked to suppress such warnings (nowarn_deprecated_function),
    is is_deprecated/3 still true?
    Suppose we have a file snagglepuss.erl containing
       -if(...).
       -deprecated(...).
       -endif.
    and a snagglepuss.beam generated from it, and suppose the .erl
    file is modified.  Should the preprocessor cause snagglepuss.erl
    to be recompiled, or what?
    (Oh, Notice that the compiler does not know about attribute
   -deprecated(), but uses an assembled list of deprecated functions
    in Erlang/OTP.  http://www.erlang.org/doc/man/compile.html)
    I think this needs to be repeated in the EEP.  Something like

	is_deprecated(Module, Function, Arity)
	There are two ways that a function can be deprecated.
	One is by using the -deprecated() attribute.  This is
	what you use to deprecate your functions, and the Xref
	tool knows about it.  The compiler does not, and this
	if-BIF doesn't either.  The other way is by listing
	the function in the compiler's table of deprecated
	functions.  This is what this if-BIF consults.
	is_deprecated(M,F,A) is true if and only if M:F/A is
	listed in that table; the nowarn_deprecated option has
	no effect on this decision.

	is_exported(M,F,A) : HOW DOES IT TELL whether F/A is
	exported from M?  Again, if we have
	-if(...).
	-export([...]).
	-endif.
	and the .erl file is newer than the .beam file, what is
	supposed to happen?  Now try this.

	-module(a).
	-if(not is_exported(b,x,0)).
	-export([x/0]).
	-endif.
	...
	-module(b).
	-if(is_exported(a,x,0)).
	-export([x/0]).
	-endif.

	Start from cold.  'a' assumes b:x/0 isn't exported,
	so it exports x/0.  'b' now exports b:x/0.  OOPS.
	'a' relied on an assumption that's false.

	My point here is that without an explicit semantics,
	I honestly do not know how to implement this EEP
	NOR DO I KNOW HOW TO USE IT SAFELY.

	is_header(...) : this seems clear enough.

	is_module(...) : ouch.  I really did not expect that
	a test for whether a module EXISTS would turn into an
	attempt to LOAD it.  Try this one:

	-module(a).
	-if(module_exists(b)).
	...
	-endif.
	...
	-module(b).
	-if(module_exists(a)).
	...
	-endif.
	...

	Do we have an infinite loop here, or do we have a
	situation where one of the modules is going to be
	compiled under assumptions that turn out to be
	false, or is this an error that must be reported?

	version(App) : " If a component consists of of
	numbers only, it will be converted to an integer".
	How?  Turning 6.0.1 into 601 is tempting, but
	consider 5.10.2.  You don't want 5.10.2 > 6.0.1.
	It's clear enough that the version is determined
	by trying to locate the app file, and thankfully
	app files don't use the preprocessor...

I did raise the issue of semantics before.
Maybe this time the importance of the issue is clearer.


On the general subject of preprocessors,
I found for my Smalltalk compiler that I needed one.
What I initially needed it for was producing a list
of test cases, because some operating system/library
features were not present everywhere.  For example,
fmtmsg(), gettext(), load average, POSIX message queues,
POSIX semaphores, a working version of the UUID library.
There is still no conditional processing in any Smalltalk
code, but lists of files and test cases, yes.

Now that tells me that there is one more if-BIF needed,
and that is something that tells you what kind of platform
you have.  Yes, Erlang code shouldn't normally depend on
that, but the Erlang code might run external programs.
Maybe this is best done by having some sort of installation
script (hello, configure!) that writes a .hrl file.  It is
certainly the kind of thing that can be added as an if-BIF
later; it's not something I'd want the EEP delayed over.





More information about the erlang-questions mailing list