We wanted to upgrade our development environment to R15B02
and ended up with a problem of different inheritance behaviour:
https://gist.github.com/3846164
The point is simple, let's imagine scenario:
- standard module a.erl with several core functions
(acts like abstract class)
- parametrized module b.erl that extends a.erl
to bring all the a's functionality
(b has always a single parameter what is proplist)
On older version of Erlang/OTP, this worked fine
and we were able to b:new ([]) what gave us {b, []}.
This does not work on R15B02 anymore :-(
We don't want to make a.erl parametrized for many reasons,
but I understand it makes some sense to bring a "base" (a)
instance with the instance of b.
The new behaviour still conforms to Richard Carlsson's paper,
because our scenario was not presented there...
The problem I see is that only the case of non-parametrized
BASE "class" has changed in R15B02...
Do we need to completely refactor our code? (add a custom
new/1 to each b-level module, turn module 'a' into a parametrized
one, etc.) How many changes are expected in future? Is it safe
to believe that once we refactor the code, no future version
will change something else?
Should we think about an alternative of doing inheritance
in our custom way otherwise?
On Oct 7, 2012, at 12:32 PM, Tomas Morstein <t...@idea.cz> wrote:
> Hello,
> We wanted to upgrade our development environment to R15B02
> and ended up with a problem of different inheritance behaviour:
> https://gist.github.com/3846164
This is quite interesting from a perspective of parameterized modules in general. They are not part of the language standard, but they are kept around since people use it. Now, since it is not part of the language standard and an experimental feature, it is subject to change without warning. You just hit such a problem.
Here is what may be wrong, one thing at a time:
* The code you present really *is* undefined behaviour. It should never have been accepted in the first place and you shouldn't write code like that. We don't know since there is no "right" specification here.
* The code works incorrectly, but the regression was not caught by the test suite.
* Parametertized modules are experimental, you are on your own and must adapt to the change when it happens.
* The code has a well-defined behaviour, but it was never made formal in the way the code generator works on these modules.
And so on. I don't know what the correct stance is to take here - but perhaps either Richard or the OTP might know what is right to do.
Jesper Louis Andersen
Erlang Solutions Ltd., Copenhagen
On Sun, Oct 7, 2012 at 12:32 PM, Tomas Morstein <t...@idea.cz> wrote: > Hello,
> We wanted to upgrade our development environment to R15B02 > and ended up with a problem of different inheritance behaviour: > https://gist.github.com/3846164
> The point is simple, let's imagine scenario: > - standard module a.erl with several core functions > (acts like abstract class) > - parametrized module b.erl that extends a.erl > to bring all the a's functionality > (b has always a single parameter what is proplist)
> On older version of Erlang/OTP, this worked fine > and we were able to b:new ([]) what gave us {b, []}. > This does not work on R15B02 anymore :-(
> We don't want to make a.erl parametrized for many reasons, > but I understand it makes some sense to bring a "base" (a) > instance with the instance of b. > The new behaviour still conforms to Richard Carlsson's paper, > because our scenario was not presented there...
> The problem I see is that only the case of non-parametrized > BASE "class" has changed in R15B02...
Had parameterized modules been a supported feature, we would most probably have have test case that would have made the breakage visible.
> How many changes are expected in future? Is it safe > to believe that once we refactor the code, no future version > will change something else?
No, that is not safe assumption for any experimental feature. An experimental feature may changed or removed at any time if it turns out to be a bad idea, or cause more problems than it solves, or that a proper implementation would need too much effort and too many other changes.
> Should we think about an alternative of doing inheritance > in our custom way otherwise?
Yes, I would recommend that.
We (the OTP team) has not reached a decision yet, but it does seem that the problems outweigh the advantages. This email lists some of the problems:
> On Sun, Oct 7, 2012 at 12:32 PM, Tomas Morstein <t...@idea.cz> wrote:
>> Hello,
>> We wanted to upgrade our development environment to R15B02
>> and ended up with a problem of different inheritance behaviour:
>> https://gist.github.com/3846164
>> The point is simple, let's imagine scenario:
>> - standard module a.erl with several core functions
>> (acts like abstract class)
>> - parametrized module b.erl that extends a.erl
>> to bring all the a's functionality
>> (b has always a single parameter what is proplist)
>> On older version of Erlang/OTP, this worked fine
>> and we were able to b:new ([]) what gave us {b, []}.
>> This does not work on R15B02 anymore :-(
>> We don't want to make a.erl parametrized for many reasons,
>> but I understand it makes some sense to bring a "base" (a)
>> instance with the instance of b.
>> The new behaviour still conforms to Richard Carlsson's paper,
>> because our scenario was not presented there...
>> The problem I see is that only the case of non-parametrized
>> BASE "class" has changed in R15B02...
> Had parameterized modules been a supported feature, we
> would most probably have have test case that would have
> made the breakage visible.
>> How many changes are expected in future? Is it safe
>> to believe that once we refactor the code, no future version
>> will change something else?
> No, that is not safe assumption for any experimental feature.
> An experimental feature may changed or removed at any
> time if it turns out to be a bad idea, or cause more problems
> than it solves, or that a proper implementation would need
> too much effort and too many other changes.
>> Should we think about an alternative of doing inheritance
>> in our custom way otherwise?
> Yes, I would recommend that.
> We (the OTP team) has not reached a decision yet, but it
> does seem that the problems outweigh the advantages. This
> email lists some of the problems:
> We use Mochiweb which makes extensive use of them.
> So is the general advice that everybody should migrate away from Mochiweb?
> Gordon
> On 8 October 2012 13:15, Björn Gustavsson <bgustavs...@gmail.com> wrote:
>> On Sun, Oct 7, 2012 at 12:32 PM, Tomas Morstein <t...@idea.cz> wrote:
>>> Hello,
>>> We wanted to upgrade our development environment to R15B02
>>> and ended up with a problem of different inheritance behaviour:
>>> https://gist.github.com/3846164
>>> The point is simple, let's imagine scenario:
>>> - standard module a.erl with several core functions
>>> (acts like abstract class)
>>> - parametrized module b.erl that extends a.erl
>>> to bring all the a's functionality
>>> (b has always a single parameter what is proplist)
>>> On older version of Erlang/OTP, this worked fine
>>> and we were able to b:new ([]) what gave us {b, []}.
>>> This does not work on R15B02 anymore :-(
>>> We don't want to make a.erl parametrized for many reasons,
>>> but I understand it makes some sense to bring a "base" (a)
>>> instance with the instance of b.
>>> The new behaviour still conforms to Richard Carlsson's paper,
>>> because our scenario was not presented there...
>>> The problem I see is that only the case of non-parametrized
>>> BASE "class" has changed in R15B02...
>> Had parameterized modules been a supported feature, we
>> would most probably have have test case that would have
>> made the breakage visible.
>>> How many changes are expected in future? Is it safe
>>> to believe that once we refactor the code, no future version
>>> will change something else?
>> No, that is not safe assumption for any experimental feature.
>> An experimental feature may changed or removed at any
>> time if it turns out to be a bad idea, or cause more problems
>> than it solves, or that a proper implementation would need
>> too much effort and too many other changes.
>>> Should we think about an alternative of doing inheritance
>>> in our custom way otherwise?
>> Yes, I would recommend that.
>> We (the OTP team) has not reached a decision yet, but it
>> does seem that the problems outweigh the advantages. This
>> email lists some of the problems:
On Mon, Oct 8, 2012 at 2:24 PM, Gordon Guthrie <gor...@vixo.com> wrote: > We use Mochiweb which makes extensive use of them.
Are you sure? What I have understood from previous email messages on this list is that many projects use "tuple modules" (which is an implementation detail in parameterized modules) and not parameterized modules directly. See for instance:
We are thinking about removing the compiler support for parameterized modules, but keeping the low-level mechanism in erlang:apply/3 and the inheritance hack in the error_handler module.
> So is the general advice that everybody should migrate away from Mochiweb?
No, it is not. It is a recommendation to think twice about using experimental fetures when writing new code or fixing old code.
> On Mon, Oct 8, 2012 at 2:24 PM, Gordon Guthrie <gor...@vixo.com> wrote:
>> We use Mochiweb which makes extensive use of them.
> Are you sure? What I have understood from previous email
> messages on this list is that many projects use "tuple modules"
> (which is an implementation detail in parameterized modules)
> and not parameterized modules directly. See for instance:
> We are thinking about removing the compiler support for parameterized
> modules, but keeping the low-level mechanism in erlang:apply/3 and
> the inheritance hack in the error_handler module.
>> So is the general advice that everybody should migrate away from Mochiweb?
> No, it is not. It is a recommendation to think twice about using
> experimental fetures when writing new code or fixing old code.
On Mon, Oct 8, 2012 at 2:33 PM, Eric Newhuis <enewh...@gmail.com> wrote: > Is there a good write-up on parameterized module alternatives anywhere?
> - always include an .hrl and pass a record instance as arg 1 ?
It depends on what exactly you are using them for.
Personally, I would define a fun with two args, where the first argument is a method name and the second argument is a tuple with the arguments. It would be used like this:
On Mon, Oct 8, 2012 at 3:00 PM, Gordon Guthrie <gor...@vixo.com> wrote: >> No, it is not. It is a recommendation to think twice about using >> experimental fetures when writing new code or fixing old code.
> Yeah, but the point of building on libraries is so as not to write code at all..
We are not doing this to break people's code, but because there is cost to keeping experimental features forever in the language.
Hopefully mochiweb will continue to work if we keep the apply/3 and error_handler hacks; if not, the maintainers of Mochiweb and we in the OTP team could probably come up with some solution to keep Mochiweb working.
On Mon, Oct 8, 2012 at 6:31 AM, Björn Gustavsson <bgustavs...@gmail.com>wrote:
> On Mon, Oct 8, 2012 at 3:00 PM, Gordon Guthrie <gor...@vixo.com> wrote:
> >> No, it is not. It is a recommendation to think twice about using
> >> experimental fetures when writing new code or fixing old code.
> > Yeah, but the point of building on libraries is so as not to write code
> at all..
> We are not doing this to break people's code, but because there is
> cost to keeping experimental features forever in the language.
> Hopefully mochiweb will continue to work if we keep the apply/3 and
> error_handler hacks; if not, the maintainers of Mochiweb and we in
> the OTP team could probably come up with some solution to keep
> Mochiweb working.
The API of mochiweb is a pair of parameterized modules, mochiweb_request
and mochiweb_response. It doesn't use tuple module hacks except maybe for
some tests. If there's some backwards compatible change that can be done to
mochiweb to ensure its future compatibility, I'd be happy to do that.
If you're worried about parameterized modules going away and breaking
mochiweb, it might be a good time to switch to cowboy or yaws. These two
are much more future-proof.