[erlang-questions] (Non)Parametrized modules, inheritance, and R15B02 issues?
Evan Miller
emmiller@REDACTED
Thu Oct 11 23:52:55 CEST 2012
On Wed, Oct 10, 2012 at 2:10 AM, Ulf Wiger <ulf@REDACTED> wrote:
> What would be good is if a list of good uses of pmods could
> be collected, and honorable workarounds suggested.
>
> This could of course be done interactively on this list.
> Present what you think is code that is not easily done well
> without pmods, and let the members of this list debate
> suitable rewrites. If good alternatives are hard to find,
> maybe that could inform some EEP for a more
> 'erlangish' extension that renders pmods truly obsolete?
I will take the bait.
As mentioned Chicago Boss uses parameterized modules in a few places
-- in SimpleBridge (the connector to Mochiweb et al) and, more
importantly, in custom controller code and in BossDB[1]. Before diving
into technical details, I will note that if support for pmods is
removed in Erlang core, then essentially every user of CB will have to
rewrite all of their model code and database accesses, and make
significant modifications to their controller code. I don't have
statistics on the number of deployments, but we do have 284 members on
our mailing list, and the project is one of the ten most-watched
Erlang projects on GitHub. So even though pmods are "experimental", a
lot of developers are watching the fate of pmods very closely.
I designed BossDB around parameterized modules because pmods allow one
to develop with a familiar ORM pattern in Erlang. I wanted a
record-oriented API that was simple, succinct, and comprehensible.
With pmods I was able to succeed in these goals. For example, to
create a new record:
Person = person:new(id, "Joe", "Armstrong")
To save it:
case Person:save() of
{ok, SavedPerson} -> % do something ...
{error, ValidationErrors} -> % do something else ...
end
To access an attribute:
Person:first_name().
"Joe"
Person:last_name().
"Armstrong"
On the inside, one can access the "internal" parameters directly to
construct additional accessors:
-module(person, [Id, FirstName, LastName]).
full_name() -> FirstName ++ " " ++ LastName.
Or perform validation:
validation_tests() ->
[{fun() -> length(FirstName) > 0, "First name must be non-empty!"},
{fun() -> length(LastName) > 0, "Last name must be non-empty!"}].
In world without pmods, these APIs would be more difficult to read and
the custom code would be more difficult to write. For example, the
accessors would look like:
person:first_name(Person)
person:last_name(Person)
The custom accessor would look like:
full_name(Person) -> first_name(Person) ++ " " ++ last_name(Person).
You'd then need to define ways of accessing the internal versions of
variables versus the accessed ones (which might be cleaned up for the
view, converted to a list, etc). Right now, with pmods, the
distinction is simple -- inside your module you can use Variable to
get the internal version, use THIS:variable() to get the
externally-visible version.
To experienced Erlang programmers, the pmod-free code above hardly
represent the worst treachery against simplicity. But here, I
personally do not find the pure-functional style of coding to be
preferable to the pmod way of doing things.
For the class of Erlang projects that I work on, the most important
thing is for code to be readable. I think it is the code readability
that has attracted other users to use Chicago Boss for their own
projects. I realize that the use of pmods comes at a cost (e.g. poor
dialyzer support), but to be honest, I really don't care. If I can
read the code and if it passes the test suite, I will ship it. I would
of course prefer that pmods be promoted to first-class citizenship so
that we could enjoy the fruits of static analysis, but given the
choice between pmods and the dialyzer for a database API, I will
choose continue to choose pmods.
I have focused the discussion here on BossDB, but there are other
times where a pmod is the most convenient way to define callback
behavior. You get a few variables "for free" in the parameter list, so
the callback writer does not have to accept the same list of variables
in every single function. For this reason the web controllers in
Chicago Boss are pmods with request information as one variable and
the current session ID as another.
I am sorry if this set of choices offends anyone's functional
sensibilities, but I think everyone should be able to code in a style
that is most productive for them. For me that style is Erlang plus
judicious use of parameterized modules. I am happy for you to put all
the warning signs that you want around the pmod documentation, and to
recount all the horrible pmod code that you've had to disentangle as
you're swapping war stories around the campfire, but I hope that
parameterized modules will exist in future versions of Erlang so that
people who find them the be a good solution for a particular class of
problems can continue to use them.
Respectfully
Evan
1. https://github.com/evanmiller/boss_db
>
> BR,
> Ulf W
>
>
> On 10 okt 2012, at 00:54, Tomas Morstein <tmr@REDACTED> wrote:
>
>>>> ...
>>
>> The problem starts when it comes to projects like ChicagoBoss
>> that we at IDEA love and intensively use every day.
>> CB uses pmods not only for simple_bridge-based web controllers,
>> but also for its sophisticated and well integrated concept of
>> data models being linked with Django templating engine in turn.
>>
>> Although I fully understand reasons why pmods and their eventual
>> pseudo-OOP behaviour (like inheritance) are not so clear as they
>> are implemented today, but in other hand, many excellent projects
>> may disappear in final result...
>>
>> I hope such a "total eclipse" is not going to happen, but our case
>> (over-using the extra unsupported and hackish features) we've just
>> adapted our technology to framework and totally forgot to standards,
>> what's in fact our own mistake.
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
--
Evan Miller
http://www.evanmiller.org/
More information about the erlang-questions
mailing list