I am close to using a behaviour as a pure interface and I feel dirty...

Stanislav Ledenev s.ledenev@REDACTED
Wed Aug 25 11:03:40 CEST 2021


OK, I'll try to give you my opinion on this topic. If I understand
your question correctly.
It may look rude but please believe me it is not my intention to be rude.

Your examples for me are the evidence of the "classic OOP" poisoning.
Remark:
I call it "classic" based on how the vast majority of the developers
perceive the idea of objects and
interaction between them.
Though I am on the side of Alan Kay's definition of the OOP - objects
communicating with messages.

Anyway, how you "slice" the world and how you make your abstractions - it
is influenced by the "classic OOP".
Erlang is the functional language (more or less) so abstractions are made
the other way:
1. Basic units are Module and Function;
2. Dynamic function calls - Module:Function(Args). So you can dynamically
(in runtime) change the module;
3. Behaviour is just a hint for a compiler to check a Module for a
presence of the required functions.

Based on these 3 points - when you write -behaviour(....) in a module you
are just saying that
this module must have a bunch of functions implemented to be successfully
compiled. It is not for
supporting your own abstractions. It is an instrument to remind you to
implement functions.

What you call "general" functionality in Erlang is simply a library
implemented as module(s).

Of course it is very tempting to call behaviour an interface, because it
looks like an interface.
But it is not because the interface in Erlang are the functions, not a
separate entity.

Example of using behaviour from my own experience.
As in almost any application I must have something where I store the data.
And requirements are very vague. So I don't know if it would be Mnesia,
PostgreSQL, file, space station or a toaster.
So I've made the behaviour which defines functions for my business logic
associated with storage.
To make it simple it is like the CRUD operations on my entities.
This behaviour is implemented as an independent rebar3 library, so other
parties (sometimes remote) can include it as a dependency.
But their implementations are included in the final application and what
implementation will be used
is defined in the configuration file.
(Pseudo) code is like this:

callbacks_db.erl:
    -module(callbacks_db).
    -callback create(Entity::my_entity_t()) -> ok | {error, Result ::
term()}.

postgresql.erl:
    -module(postgresql).
    -behaviour(callbacks_db).
    create(Entity) -> ....

toaster_able_to_storage_data.erl:
    -module(toaster_able_to_storage_data).
    -behaviour(callbacks_db).
    create(Entity) -> ....

main_app.config:
     {main_app, [
         {db, #{mod => postgresql}} % If you are using a toaster use
"toaster_able_to_storage_data"
     ]}

main_app.erl:
    some_function(DBMod) ->
        Entity = create_entity(...),
        DBmod:create(Entity).

That is all about behaviour.

ср, 25 авг. 2021 г. в 00:46, Brett Hemes <brhemes@REDACTED>:

> > Erlang's behaviour is NOT an interface!
>
> > If you are looking for some analogy from other languages the closest one
> is abstract classes in C#.
>
>
>
> This isn’t very helpful...  it is the exact same response I find in the
> forums with no reasoning behind it.  I don’t need analogies either; I
> understand what behaviours are “supposed” to be from the documentation and
> comments (perhaps this wasn’t made clear by my post).  Where I fall short
> is “why” are behaviours limited to such and why aren’t more people asking
> the same questions I am stuck on (regarding polymorphism)?  My logic was:
> yes, this has been asked and discussed some in the past with no real
> resolution that I could find... therefore, users must be content/accepting
> of the tools provided.  I am not so naive to think I am the first to
> need/want such, so there must be a disconnect.
>
>
>
> I posted my example to motivate my questioning hoping for some insight
> and/or comfort.  As of now, I have proceeded with storing “meta refs” to my
> child servers that are module/reference tuples (along with some dangerous
> and future-maintenance-issue-causing assumptions regarding their
> “interface”)... and it’s works... it just smells, and I am always eager to
> learn and find the right/better/best way.
>
>
>
> Aside: a colleague came across this repo (
> https://github.com/eldarko/epolymorph) while digging and the readme seems
> to capture my use case almost exactly...
>
>
>
> Brett
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20210825/62d00325/attachment.htm>


More information about the erlang-questions mailing list