[erlang-questions] Breaking backwards compatibility in Release 17.0-rc2

Jesper Louis Andersen <>
Fri Feb 28 00:06:34 CET 2014


Release 17.0 brings two changes which prove to take some work getting
around.

1. utf-8 is now the default encoding.

This is a rather insignificant change. The source code which uses latin1
can be fixed by one of three ways:

* Tell the compiler the file is latin1. This won't work going forward but
works now.
* Change the file to utf-8. This won't work going backward a long way. But
it will work going backwards for a bit.
* Change the file to ASCII. This works both backward and forward as long as
we want.

This is a benign problem. I have tried compiling some projects and it turns
out there are numerous repositories which needs fixing now. But the fix is
rather simple.

2. Dialyzer dislikes queue(), dict(), ...

Dialyzer now prefers using queue:queue() and the like. This is *definitely*
the right thing to support as it is much more consistent with the rest of
the system and doesn't treat certain types as magically introduced types.

-module(z).

-export([f/1]).

-spec f(queue:queue()) -> queue:queue().
f(Q) -> queue:in(3, Q).

Which is nice, but this doesn't work on R16B03:

z.erl:5: referring to built-in type queue as a remote type; please take out
the module name
z.erl:5: referring to built-in type queue as a remote type; please take out
the module name

So here, I have no way of getting my source code to work with both R16 and
17.0 easily. There is no transition period so-to-speak. Many projects run
with warnings-as-errors and they are in trouble:

* They can't compile
* They can remove the warnings-as-errors but this defeats the purpose
* They will have warnings spewed out over the console all the time

In the case of crypto:hash/2, we had somewhat the same situation. Prominent
projects like Yaws, and lesser projects like Emysql has EPP macros in place
as well as detection in order to figure out what to do. Or you can disable
the warnings in this case specifically for this. But can I do the same with
wrong type specs? Also, this workaround is done in almost every project out
there, which is darn irritating.

I don't know what we need to solve this. At one point, I would really like
to have a set of feature flags

http://www.lispworks.com/documentation/HyperSpec/Body/v_featur.htm , ZFS,
...

where you have a way to compile-time scrutinize what your environment
supports. Another way to solve it is the variant Go uses, namely "build
constraints"

http://golang.org/pkg/go/build/#pkg-overview

which will mention under which circumstances to include a file as a part of
an application. This would allow for easy handling of crypto:hash/2, but I
do note it will fail on the dialyzer problem. It looks like the only sane
way to solve that is to allow both queue() and queue:queue() as aliases for
a major release and then proceed to remove queue().

Am I completely wrong here? I can accept languages evolve and that Release
17 has maps which will be used and break a lot of software for R16 quickly.
But I also feel we should have some way of having a process so there is a
way to handle this gracefully going forward. It is natural for libraries
and languages to evolve and break compatibility. Yet, it should be easy to
handle for programmers. There is much time wasted, which could be used
better were there a nice solution.

Thoughts?

-- 
J.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20140228/ce7b0bff/attachment-0001.html>


More information about the erlang-questions mailing list