[erlang-questions] Third draft of EEP 44 - Additional preprocessor directives
Richard A. O'Keefe
ok@REDACTED
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