<div dir="ltr"><div class="gmail_quote"><br><div dir="ltr"><span class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="m_-6200114570220188649gmail-im" style="font-size:12.8px"><div>> -pure([f/1, g/0, h/3]).<br></div><div><br></div></span><div style="font-size:12.8px">So, you declare f/1 is pure, but how do you really know it is pure? Meaning it should be a way to prove f/1 is pure, at least with some tool like dialyzer</div></blockquote><div><br></div></span><div>if f/1 is NIF there is little hope of proving that </div><div>so in general i think ti should be either provable (meaning it is not NIF and uses only pure functions) or declared as such </div><div><br></div><div>i think we should go with "trust" here. If function is NIF it should be declared as pure, otherwise tool is to assume it is not </div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Sep 28, 2017 at 10:41 AM, Roman Galeev <span dir="ltr"><<a href="mailto:jamhedd@gmail.com" target="_blank">jamhedd@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"><span><div>> -pure([f/1, g/0, h/3]).<br></div><div><br></div></span><div>So, you declare f/1 is pure, but how do you really know it is pure? Meaning it should be a way to prove f/1 is pure, at least with some tool like dialyzer.</div><img src="https://mltrk.io/pixel/DEigk3DuVHWzLEAB09Z1?rid=DEigk3DuVHWzLEAB09Z1" width="1" height="1" border="0"></div><div class="gmail_extra"><div><div class="m_-6200114570220188649h5"><br><div class="gmail_quote">On Thu, Sep 28, 2017 at 10:27 AM, zxq9 <span dir="ltr"><<a href="mailto:zxq9@zxq9.com" target="_blank">zxq9@zxq9.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On 2017年09月28日 木曜日 10:01:12 you wrote:<br>
> > I really wish Dialyzer accepted (and checked) explicit declarations of<br>
> purity.<br>
><br>
> i could not agree more<br>
> that would be useful feature and amazing time saver!<br>
><br>
> I am currently working on a toll that creates DB of function properties,<br>
> and motivation was exactly finding non pure functions in any given<br>
> project.<br>
<br>
</span>I've messed around with this a bit and, not liking syntaxtic additions<br>
(for the most part), I've played around a little with this idea. The one<br>
I've come up with that allows building a checkable graph is what I'm doing<br>
already:<br>
<br>
-pure([f/1, g/0, h/3]).<br>
<br>
So that works just like an -export attribute and when the compiler rolls<br>
over it you actually get a nice list in module_info:<br>
<br>
1> zuuid:module_info(attributes).<br>
[{vsn,[16118523173542954775021<wbr>2483364357911358]},<br>
 {author,"Craig Everett <<a href="mailto:zxq9@zxq9.com" target="_blank">zxq9@zxq9.com</a>>"},<br>
 {behavior,[application]},<br>
 {pure,[{v3,1},<br>
        {v3,2},<br>
        {v3_hash,2},<br>
        {v5,1},<br>
        {v5,2},<br>
        {v5_hash,2},<br>
        {read_uuid,1},<br>
        {read_uuid_string,1},<br>
        {read_mac,1},<br>
        {read_mac_string,1},<br>
        {string,1},<br>
        {string,2},<br>
        {binary,1},<br>
        {binary,2},<br>
        {strhexs_to_uuid,1},<br>
        {strhexs_to_mac,1},<br>
        {strhexs_to_integers,1},<br>
        {bins_to_strhexs,1},<br>
        {binary_to_strhex,1}]}]<br>
<br>
Quite easy to build a graph around this sort of data. And it comes only at<br>
the cost of actually including a -pure declaration.<br>
<br>
The problem, of course, is actually making a -pure declaration and keeping<br>
it in sync with the module code over time -- and that this is invisible to<br>
Dialyzer right now.<br>
<br>
That said, if no unsafe calls or actions are taken in a function Dialyzer<br>
could infer which functions are pure and help generate such a list. Even<br>
better, of course would be if it knew the difference and examined each<br>
function to build the graph of pureness automatically...<br>
<br>
But I digress.<br>
<br>
Save the (maybe not easy) task of making Dialyzer able to infer purity<br>
(and this is impossible anyway when Dialyzer hits a wall of ambiguity<br>
such as a call to M:F(A) or apply(M, F, A) -- which are pretty important!),<br>
it would even nicer if we had a pure function spec declaration form.<br>
<br>
-pure f() -> term().<br>
<br>
And just leave the original<br>
<br>
-spec f() -> {ok, Value :: term()} | {error, Reason :: term()}.<br>
<br>
form alone.<br>
<br>
That shouldn't break any old code, and leave a safe path to updating the<br>
stdlib and internals of existing projects... without anything significant<br>
changing until people are ready for it.<br>
<br>
And no new syntax.<br>
<br>
Where a new bit of syntax may be nice is if, for example, a way to declare<br>
*what* side effects a function has or might have. I haven't any good idea<br>
how to go about that because I've never thought of it or seen a system that<br>
declares categories of side-effects... but its an interesting idea that<br>
might help make "unit testing" of modules that have side effects actually<br>
mean something (for once) and move it closer to the usefulness of actual<br>
user testing (which is amazing at finding the boneheaded, easy to fix,<br>
90% of bugs that are concrete and repeatable that unit tests are for some<br>
reason consistently blind to).<br>
<div class="m_-6200114570220188649m_8309527237676494278HOEnZb"><div class="m_-6200114570220188649m_8309527237676494278h5"><br>
-Craig<br>
______________________________<wbr>_________________<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" rel="noreferrer" target="_blank">http://erlang.org/mailman/list<wbr>info/erlang-questions</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div></div></div><span>-- <br><div class="m_-6200114570220188649m_8309527237676494278gmail_signature" data-smartmail="gmail_signature"><div dir="ltr">With best regards,<div>     Roman Galeev,</div><div>     <a href="tel:+420%20702%20817%20968" value="+420702817968" target="_blank">+420 702 817 968</a></div></div></div>
</span></div>
<br>______________________________<wbr>_________________<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" rel="noreferrer" target="_blank">http://erlang.org/mailman/list<wbr>info/erlang-questions</a><br>
<br></blockquote></div><br></div>
</div></div></div><br></div>