<div dir="ltr">What you have implemented *is not protocols*, so the details of your implementation of "non-extensible protocols" are irrelevant. I certainly have not said that it is not possible in Erlang, because it *obviously* is possible to have protocols given that Elixir does it with the same runtime. What I have said is that it's not idiomatic to do such things, so you should probably try and solve your problems in a different way, with more concrete implementations (such as explicit passing of funs or {Module, State} tuples).<div>
<br></div><div>As Fred said, there's a simple mechanical transformation from tuple funs (what you have called "stateful modules") to standard Erlang code. Fred's translation is slightly off though, for some reason the module name is included in the argument tuple.</div>
<div><br></div><div>%% Using tuple calls (*strongly* discouraged)</div><div>f(M, Arg) -> M:call(Arg).</div><div><br></div><div>%% Without tuple calls</div><div>f({M, State}, Arg) -> M:call(Arg, {M, State}).</div><div>
<br></div><div>I am suggesting that what you have proposed is bad practice. There are other ways to implement exactly what you have shown with only a little bit more syntax.</div><div><br></div><div>See <a href="http://www.erlang.org/doc/efficiency_guide/functions.html">http://www.erlang.org/doc/efficiency_guide/functions.html</a> for official documentation on tuple funs. In summary: they exist and are supported by the runtime for compatibility reasons, but their implementation is slow and their use is strongly discouraged.</div>
<div><br></div><div>-bob</div><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Dec 13, 2013 at 10:19 AM, Kaveh Shahbazian <span dir="ltr"><<a href="mailto:kaveh.shahbazian@gmail.com" target="_blank">kaveh.shahbazian@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif">"<span style="font-family:arial,sans-serif;font-size:13px">The trouble with implementing this in Erlang is that in order to do it you need to have some mutable data structure in the runtime that changes based on which modules are loaded";</span></div>

<div class="gmail_default" style="font-family:verdana,sans-serif"><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div class="gmail_default" style="font-family:verdana,sans-serif"><span style="font-family:arial,sans-serif;font-size:13px">From this I assume you say this is not possible in Erlang but </span><u style="font-family:arial,sans-serif;font-size:13px"><b>this thing already works in Erlang</b></u><span style="font-family:arial,sans-serif;font-size:13px"> and does not mutate anything. So it is already implemented in Erlang.</span></div>

<div class="gmail_default" style="font-family:verdana,sans-serif"><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div class="gmail_default" style="font-family:verdana,sans-serif"><span style="font-family:arial,sans-serif;font-size:13px">Now are you suggesting this is a bad practice? And should be avoided?</span></div>

</div><div class="gmail_extra"><div class="im"><br clear="all"><div><div dir="ltr"><div><span style="font-family:tahoma,sans-serif;font-size:large">Kaveh Shahbazian</span><br></div><div><font size="1" face="arial narrow, sans-serif"><div>

“Walking on water and developing software from a specification are easy if both are frozen.” </div><div>― Edward Berard</div><div><a href="http://goo.gl/ZZ2TMu" target="_blank"><img></a><br>
</div><div><a href="http://stackoverflow.com/users/54467/kaveh-shahbazian" target="_blank"><img></a><br></div></font></div></div></div>
<br><br></div><div><div class="h5"><div class="gmail_quote">On Fri, Dec 13, 2013 at 9:36 PM, Bob Ippolito <span dir="ltr"><<a href="mailto:bob@redivi.com" target="_blank">bob@redivi.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div dir="ltr">I think you're a bit confused here, because your implementation of ?protocolX(…) doesn't work like Elixir protocols. The trouble with implementing this in Erlang is that in order to do it you need to have some mutable data structure in the runtime that changes based on which modules are loaded, since any module can define an implementation for some protocol. Elixir's defprotocol just creates a new module for the given protocol (e.g. 'Elixir.Enum'), and defimpl creates a separate module for each implementation of a protocol (e.g. 'Elixir.Enum.List').<div>


<br></div><div>Erlang simply does not have any built-in support for the kind of dispatch you're looking for. Parameterized modules were similar to what you are proposing (but not like Elixir's protocols!), but they have been deprecated. If you really feel the need to write very generic code, maybe Erlang is not the language for you. Erlang works best when you can do everything with concrete implementations. Elixir would likely fit more abstract use cases better, but note that there is some runtime performance cost for this indirection.</div>


<div><br></div><div>Haskell's type classes are also quite interesting too, as the import of a type class instance doesn't propagate beyond the compilation unit so you don't have as much of a namespace issue. The compiler can also get rid of the indirection in most cases so there's not necessarily any cost for using abstractions in that universe.</div>


<div><br></div><div>In any case, I can't think of a way to reasonably implement this in Erlang using idioms that mesh well with the rest of Erlang. There is no OTP standard for this kind of thing, and there isn't likely to be a good way to do it any time soon. If there was an OTP "interface" standard, surely we'd have a hook to customize what "~p" means to io_lib for our own types! But alas, we can't really even define our own abstract data types in Erlang, just type aliases over the built-in concrete types.</div>

<span><font color="#888888">
<div><br></div><div>-bob</div><div><br></div></font></span></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Dec 13, 2013 at 8:56 AM, Kaveh Shahbazian <span dir="ltr"><<a href="mailto:kaveh.shahbazian@gmail.com" target="_blank">kaveh.shahbazian@gmail.com</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif">First "stringer" was a sample for (turned out it was a bad one) simulating protocols. So one could write (it can be more complicated, but whatever):</div>



<div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default"><div class="gmail_default"><font face="verdana, sans-serif">test(V) -></font></div><div class="gmail_default"><font face="verdana, sans-serif">    X = ?protocolX(V),</font></div>



<div class="gmail_default"><font face="verdana, sans-serif">    X:act1(),</font></div><div class="gmail_default"><font face="verdana, sans-serif">    X:act2(),</font></div><div class="gmail_default"><font face="verdana, sans-serif">    % ...</font></div>



<div class="gmail_default"><font face="verdana, sans-serif">    X:actN(SomeArguments),</font></div><div class="gmail_default"><font face="verdana, sans-serif">    OtherThings().</font></div><div class="gmail_default"><font face="verdana, sans-serif"><br>



</font></div><div class="gmail_default"><font face="verdana, sans-serif">And act1 .. actN are members of 'protocolX'. This way it's clear that 'V' is behaving as a 'X' (much like interfaces in C#; am I too corrupted?).</font></div>



<div class="gmail_default"><font face="verdana, sans-serif"><br></font></div><div class="gmail_default"><font face="verdana, sans-serif">BTW since I am no Erlang guru, I will follow the rules (for a foreseeable future) as you say here.</font></div>



</div></div><div class="gmail_extra"><br clear="all"><div><div dir="ltr"><div><span style="font-family:tahoma,sans-serif;font-size:large">Kaveh Shahbazian</span><br></div><div><font size="1" face="arial narrow, sans-serif"><div>


<div>
“Walking on water and developing software from a specification are easy if both are frozen.” </div><div>― Edward Berard</div></div><div><a href="http://goo.gl/ZZ2TMu" target="_blank"><img></a><br>
</div><div><a href="http://stackoverflow.com/users/54467/kaveh-shahbazian" target="_blank"><img></a><br></div></font></div></div></div><div><div>
<br><br><div class="gmail_quote">On Fri, Dec 13, 2013 at 5:32 PM, Fred Hebert <span dir="ltr"><<a href="mailto:mononcqc@ferd.ca" target="_blank">mononcqc@ferd.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



Hi.<br>
<br>
Despite what Joe says in his book, the history of the feature is that<br>
tuple calls, the form you're using, were kept to allow the deprecation<br>
of parametrized modules.<br>
<br>
In my humble opinion, the 'stateful module' things you're trying to<br>
accomplish for you stringification is non-intuitive and not erlangish (I<br>
would be confused by reading that in a code base). May I suggest the<br>
simpler form, without changing your module:<br>
<br>
    stringer:to_string(MyValue)<br>
<br>
instead? You will notice it even saves two characters when being called<br>
over:<br>
<br>
    ?stringer(MyValue):to_string().<br>
<br>
Without including the macro definition work required, and is more<br>
idiomatic overall. To use it as a function, simply use<br>
<br>
    F = fun stringer:to_string/1,<br>
    F(MyValue).<br>
<br>
Regards,<br>
Fred.<br>
<div><br>
On 12/13, Kaveh Shahbazian wrote:<br>
> I do not thing so. Parametrized modules are different than stateful<br>
> modules. Parametrized modules are deprecated and they were always<br>
> provisional.<br>
><br>
> Joe Armstrong in Programming Erlang (2nd Edition, Page 418) talked about<br>
> them and in this same book he was promoting "coming soon" features of R17<br>
> and It's highly unlikely for them to be deprecated.<br>
><br>
> Kaveh Shahbazian<br>
> “Walking on water and developing software from a specification are easy if<br>
> both are frozen.”<br>
> ― Edward Berard<br>
</div>> <<a href="http://goo.gl/ZZ2TMu" target="_blank">http://goo.gl/ZZ2TMu</a>><br>
> <<a href="http://stackoverflow.com/users/54467/kaveh-shahbazian" target="_blank">http://stackoverflow.com/users/54467/kaveh-shahbazian</a>><br>
<div><div>><br>
><br>
> On Fri, Dec 13, 2013 at 11:40 AM, Dmitry Kolesnikov<br>
> <<a href="mailto:dmkolesnikov@gmail.com" target="_blank">dmkolesnikov@gmail.com</a>>wrote:<br>
><br>
> > Hello,<br>
> ><br>
> > Essentially you are trying to use parametrized modules, which get<br>
> > deprecated in R14/15 and dropped from R16.<br>
> > See for details:<br>
> >  * <a href="http://www.erlang.org/news/35" target="_blank">http://www.erlang.org/news/35</a><br>
> >  * <a href="http://www.erlang.se/workshop/2003/paper/p29-carlsson.pdf" target="_blank">http://www.erlang.se/workshop/2003/paper/p29-carlsson.pdf</a><br>
> ><br>
> > This type of problems are solvable either via pattern match or currying:<br>
> ><br>
> > -module(stringer).<br>
> > -export([stringer/1,sample/0]).<br>
> ><br>
> > stringer(V) when is_list(V) -><br>
> >     fun() -> to_string(V, nop) end;<br>
> > stringer(V) when is_atom(V) -><br>
> >     fun() -> to_string(V, nop) end;<br>
> > stringer(_V) -><br>
> >     fun() -> not_implemented end.<br>
> ><br>
> > to_string(V, _Nop) -><br>
> >     Buffer = io_lib:format("~p",[V]),<br>
> >     lists:flatten(Buffer).<br>
> ><br>
> > sample() -><br>
> >     io:format("~p~n", [(stringer([1,2]))()]),<br>
> >     io:format("~p~n", [(stringer(cute_atom))()]),<br>
> >     io:format("~p~n", [(stringer(13))()]).<br>
> ><br>
> ><br>
> > Best Regards,<br>
> > Dmitry<br>
> ><br>
> > On Dec 13, 2013, at 8:31 AM, Kaveh Shahbazian <<a href="mailto:kaveh.shahbazian@gmail.com" target="_blank">kaveh.shahbazian@gmail.com</a>><br>
> > wrote:<br>
> ><br>
> > I wanted to write something like ((IStringer)object).ToString() (in C#)<br>
> > in Erlang. After some studying I've learnt that Elixir has something called<br>
> > Protocols that pretty much resembles the same thing of C# (in an inside-out<br>
> > manner). Then I came up with this idea/code in Erlang - which is nice<br>
> > enough to me like:<br>
> ><br>
> > ?stringer(my_val):to_string().<br>
> ><br>
> > And it either returns the expected value or not_implemented atom!<br>
> ><br>
> > But 2 questions:<br>
> ><br>
> > 1 - Why nobody use this or promote things based on stateful modules in<br>
> > Erlang? (OTP aside and from talking to some Erlangers they did not know<br>
> > that actually OTP is built around this! So really there is a need to change<br>
> > how Erlang is being taught and promoted. It's possible that I am confused.).<br>
> ><br>
> > 2 - Why I get this warning? That call actually never fails.<br>
> ><br>
> > The warning:<br>
> ><br>
> > stringer.erl:18: Warning: invalid module and/or function name; this call will always fail<br>
> > stringer.erl:19: Warning: invalid module and/or function name; this call will always fail<br>
> > stringer.erl:20: Warning: invalid module and/or function name; this call will always fail<br>
> ><br>
> > The code:<br>
> ><br>
> > -module(stringer).<br>
> > -export([to_string/1,sample/0]).<br>
> ><br>
> > -define(stringer(V), {stringer, V}).<br>
> ><br>
> > to_string({stringer, V}) when is_list(V) -><br>
> >     to_string(V, nop);<br>
> > to_string({stringer, V}) when is_atom(V) -><br>
> >     to_string(V, nop);<br>
> > to_string({stringer, _V}) -><br>
> >     not_implemented.<br>
> ><br>
> > to_string(V, _Nop) -><br>
> >     Buffer = io_lib:format("~p",[V]),<br>
> >     lists:flatten(Buffer).<br>
> ><br>
> > sample() -><br>
> >     io:format("~p~n", [?stringer([1,2]):to_string()]),<br>
> >     io:format("~p~n", [?stringer(cute_atom):to_string()]),<br>
> >     io:format("~p~n", [?stringer(13):to_string()]).<br>
> ><br>
> > And the output is:<br>
> ><br>
> > "[1,2]"<br>
> > "cute_atom"<br>
> > not_implemented<br>
> ><br>
> >  _______________________________________________<br>
> > erlang-questions mailing list<br>
> > <a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
> > <a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
> ><br>
> ><br>
> ><br>
<br>
> _______________________________________________<br>
> erlang-questions mailing list<br>
> <a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
> <a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br>
</div></div></blockquote></div><br></div></div></div>
<br>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br></blockquote></div><br></div>
</div></div></blockquote></div><br></div></div></div>
</blockquote></div><br></div>