Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ?OTP_RELEASE, -if and -elif to the preprocessor #1810

Merged
merged 4 commits into from
May 17, 2018

Conversation

tomas-abrahamsson
Copy link
Contributor

This PR is based on @bjorng's reference implementation of eep-0044 with changes described below. There were discussion when the eep was first introduced, so I have removed some things that I think were never settled.

I removed the if/elif builtin functions is_deprecated(M,F,A), is_exported(M,F,A), is_module(Atom), version(App) and is_header(File) for which there were concerns. This remains:

  • The predefined OTP_RELEASE macro (an integer)
  • The -if(Condition). and -elif(Condition). preprocessor constructs
  • The if/elif builtin function defined(Symbol)

I updated the epp_SUITE accordingly and added documentation.

I have rebased the reference implementation branch to master. In the rebased commits, I have kept the original author as I have basically mostly only been removing things (builtin functions).

bjorng and others added 4 commits May 6, 2018 23:43
Add a new pre-defined macro called OTP_RELEASE that will expand
to an integer being the OTP version. Thus, in OTP 19 the value will
be the integer 19.

The OTP_RELEASE macro is particularly useful in order to have
different source code depending on new language features or new
features in the type specification syntax. Those features are only
introduced in major versions of OTP.

To be truly useful, the -if preprocessor directive need to be
implemented. That is the purpose of the next commit.

Code that will need to work in both OTP 18 and OTP 19 can be
structured in the following way:

-ifdef(OTP_RELEASE).
%% Code that only works in OTP 19 and later.
-else.
%% Code that will work in OTP 18.
-endif.
Libraries or applications that support more than one major
release of OTP may need to use conditional compilation of
Erlang source code. Here are few examples where it would be
necessary or desirable:

* To support a new data type or language feature only available
  in the latest major release (real-world examples: maps and the
  stacktrace syntax).

* To avoid warnings for deprecated functions.

* To avoid dialyzer warnings.

Previously, to do conditional compilation, one would have to
use a parse transform or some external tool such as 'autoconf'.

To simplify conditional compilation, introduce the -if and -elif
preprocessor directives, to allow code like this to be written:

-if(?OTP_RELEASE =:= 21).
  %% Code that will only work in OTP 21.
-else.
  %% Fallback code.
-endif.

What kind of expressions should be allowed after an -if?

We certainly don't want to allow anything with a side effect,
such as a '!' or a 'receive'. We also don't want it to be
possible to call erlang:system_info/1, as that could make the
code depedent on features of the run-time system that could
change very easily (such as the number of schedulers).

Requiring the expression to be a guard expression makes most
sense. It is to explain in the documentation and easy for users
to understand. For simplicity of implementation, only a single
guard expression will be supported; that is, the ',' and ';' syntax
for guards is not supported.

To allow some useful conditions to be written, there is a special
built-in function:

defined(Symbol) tests whether the preprocessor symbol is defined,
just like -ifdef. The reason for having this defined/1 is that
the defined test can be combined with other tests, for example:
'defined(SOME_NAME) andalso ?OTP_RELEASE > 21'.
@CLAassistant
Copy link

CLAassistant commented May 9, 2018

CLA assistant check
All committers have signed the CLA.

@tomas-abrahamsson
Copy link
Contributor Author

Hmm.. The Travis Linux64SmokeTest was aborted after 10 seconds of silence just after Network availability confirmed. In another PR, it started git-cloning the otp repo after that point, but in that never happened here. I suppose this travis error was not caused by the commit, but I also could not find a way to retrigger the job.

@rickard-green rickard-green added the team:VM Assigned to OTP team VM label May 14, 2018
@bjorng bjorng added the testing currently being tested, tag is used by OTP internal CI label May 16, 2018
@bjorng
Copy link
Contributor

bjorng commented May 17, 2018

The OTP Technical Board approved this pull request today.

@bjorng bjorng merged commit 52fe211 into erlang:master May 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team:VM Assigned to OTP team VM testing currently being tested, tag is used by OTP internal CI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants