<div dir="ltr"><br><div class="gmail_quote">---------- Forwarded message ----------<br>From: <b class="gmail_sendername">James Fish</b> <span dir="ltr"><<a href="mailto:james@fishcakez.com">james@fishcakez.com</a>></span><br>Date: 18 December 2014 at 20:24<br>Subject: Re: [erlang-questions] Is it possible to have nested parametrised types when the base type is opaque?<br>To: James Aimonetti <<a href="mailto:james@2600hz.com">james@2600hz.com</a>><br><br><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On 18 December 2014 at 18:53, James Aimonetti <span dir="ltr"><<a href="mailto:james@2600hz.com" target="_blank">james@2600hz.com</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">-----BEGIN PGP SIGNED MESSAGE-----<br>
Hash: SHA1<br>
<br>
Le 2014-12-18 07:32, James Fish a écrit :<br>
<div><div>> Hi all,<br>
><br>
> I am never one to doubt that dialyzer is correct, and I am wrong.<br>
> In this case I am perplexed by the warning generated with nested<br>
> parametrised types. For example if a module defines the type:<br>
><br>
> -type myqueue(Item) :: {myqueue, queue:queue({integer(), Item})}.<br>
><br>
> And another module wishes to use myqueue/1:<br>
><br>
> -spec in(integer(), myqueue(integer()) -> myqueue(integer()).<br>
><br>
> Dialyzer will warn that success typing has the second argument and<br>
> result of the form {myqueue, queue:queue({integer(), any()})}. What<br>
> is the subtlety that I am missing?<br>
><br>
> You can find two sample modules attached. One module with a<br>
> parametrised queue and another with a parametrised "parametrised"<br>
> queue using the first module. Dialyzer has alot of fun with the<br>
> second module. If queue:queue() was not opaque no warnings are<br>
> generated and if myqueue:myqueue() is not opaque an extra warning<br>
> is generated.<br>
><br>
> Thank you,<br>
><br>
> James<br>
><br>
><br>
><br>
</div></div>> _______________________________________________ erlang-questions<br>
> mailing list <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>
It seems, in the parameterized version, you are inserting Item only,<br>
not a tuple.<br>
<br>
Compare myqueue.erl:<br>
<br>
    #myqueue{queue=queue:in({1, Item}, Q)}.<br>
<br>
to myqueue_params.erl:<br>
<br>
    P#myqueue_params{myqueue=myqueue:in(Item, Q)}.<br>
<br>
The first is a tuple and the second is an integer.<br>
<br>
That's my initial reading, anyway.<br>
<br>
- --<br>
James Aimonetti<br>
Lead Systems Architect / Impressionable Scallywag<br>
"I thought I fixed that"<br>
<br>
2600Hz | <a href="http://2600hz.com" target="_blank">http://2600hz.com</a><br>
<a href="mailto:sip%3Ajames@2600hz.com" target="_blank">sip:james@2600hz.com</a><br>
tel:415.886.7905<br>
irc:mc_ @ freenode<br>
-----BEGIN PGP SIGNATURE-----<br>
Version: GnuPG v1<br>
Comment: Using GnuPG with Thunderbird - <a href="http://www.enigmail.net/" target="_blank">http://www.enigmail.net/</a><br>
<br>
iQEcBAEBAgAGBQJUkyK9AAoJENTKa+JPXCVgtpAIAJkSgQcA98T1VYyZeTEqhU9t<br>
B5D+aBf964qXqcTcFPJuquEhEBp59ULEj6A96OYc+QLiN0D1Lk8SdHy4YHdCtuSQ<br>
HrIA1sVsTz6Jj3EgyqjwtMjCVco25ZQiDs1cT7jhGUKCi2OUIpjpgi6Vb+UwASfw<br>
GVry3XJhobgNaH3xfDdx9h8S766k0B/JqtykK6fVbjoIJVxfnQ6yqz6w5604tjw1<br>
VdIyPwml4oAxOndQe0gxiAP5A7P8AyjAs0TvpRMILOm7gtE3tj4JM2ouFgK7VjY4<br>
aX8PGfoeKkazf4XJbuQSJXTODGikGLQSgnhmUz8Cd/MRKvnf4WCfaKl75JWPhl0=<br>
=yQIn<br>
-----END PGP SIGNATURE-----<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></blockquote><div><br></div></div></div><div>Thank you for taking a look. That is actually intentional, the myqueue module is wrapping the queue module and also acting as a queue. It enqueues a 2-tuple, the first an integer and the second element is the item enqueued though its own API (myqueue:in/2). This means that a myqueue(Item) contains a queue:queue({integer(), Item}).<br><br></div><div>The myqueue_params module wraps the myqueue module and simply enqueues an integer directly to myqueue. Thus contains a myqueue:myqueue(integer()), as per the -spec.<br><br></div><div>However dialyzer (at least in 17.*) produces the following warnings:<br><br>myqueue_params.erl:10: Function new/0 has no local return<br>myqueue_params.erl:11: The attempt to match a term of type myqueue:myqueue(integer()) against the variable _ breaks the opaqueness of the term<br>myqueue_params.erl:14: Function in/2 has no local return<br>myqueue_params.erl:15: The call myqueue:in(Item::integer(),Q::myqueue:myqueue(integer())) does not have an opaque term of type myqueue:myqueue(_) as 2nd argument<br><br></div><div>Firstly the warning on line 11. This is warning that matching against the _ variable breaks opaqueness. A _ variable is never used and if it did I am unsure how matching against it would break an opaque contract.<br><br></div><div>Secondly the warning on line 15. Dialyzer is producing a warning that appears contradictory as it appears to be warning about an over specification (i.e. the spec is less allowing that it needs to be), though does not class it as such.<br></div></div></div></div>
</div></div>