[erlang-questions] Fwd: Is it possible to have nested parametrised types when the base type is opaque?

James Fish james@REDACTED
Thu Dec 18 22:03:48 CET 2014


---------- Forwarded message ----------
From: James Fish <james@REDACTED>
Date: 18 December 2014 at 20:24
Subject: Re: [erlang-questions] Is it possible to have nested parametrised
types when the base type is opaque?
To: James Aimonetti <james@REDACTED>



On 18 December 2014 at 18:53, James Aimonetti <james@REDACTED> wrote:
>
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Le 2014-12-18 07:32, James Fish a écrit :
> > Hi all,
> >
> > I am never one to doubt that dialyzer is correct, and I am wrong.
> > In this case I am perplexed by the warning generated with nested
> > parametrised types. For example if a module defines the type:
> >
> > -type myqueue(Item) :: {myqueue, queue:queue({integer(), Item})}.
> >
> > And another module wishes to use myqueue/1:
> >
> > -spec in(integer(), myqueue(integer()) -> myqueue(integer()).
> >
> > Dialyzer will warn that success typing has the second argument and
> > result of the form {myqueue, queue:queue({integer(), any()})}. What
> > is the subtlety that I am missing?
> >
> > You can find two sample modules attached. One module with a
> > parametrised queue and another with a parametrised "parametrised"
> > queue using the first module. Dialyzer has alot of fun with the
> > second module. If queue:queue() was not opaque no warnings are
> > generated and if myqueue:myqueue() is not opaque an extra warning
> > is generated.
> >
> > Thank you,
> >
> > James
> >
> >
> >
> > _______________________________________________ erlang-questions
> > mailing list erlang-questions@REDACTED
> > http://erlang.org/mailman/listinfo/erlang-questions
> >
>
> It seems, in the parameterized version, you are inserting Item only,
> not a tuple.
>
> Compare myqueue.erl:
>
>     #myqueue{queue=queue:in({1, Item}, Q)}.
>
> to myqueue_params.erl:
>
>     P#myqueue_params{myqueue=myqueue:in(Item, Q)}.
>
> The first is a tuple and the second is an integer.
>
> That's my initial reading, anyway.
>
> - --
> James Aimonetti
> Lead Systems Architect / Impressionable Scallywag
> "I thought I fixed that"
>
> 2600Hz | http://2600hz.com
> sip:james@REDACTED
> tel:415.886.7905
> irc:mc_ @ freenode
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1
> Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
>
> iQEcBAEBAgAGBQJUkyK9AAoJENTKa+JPXCVgtpAIAJkSgQcA98T1VYyZeTEqhU9t
> B5D+aBf964qXqcTcFPJuquEhEBp59ULEj6A96OYc+QLiN0D1Lk8SdHy4YHdCtuSQ
> HrIA1sVsTz6Jj3EgyqjwtMjCVco25ZQiDs1cT7jhGUKCi2OUIpjpgi6Vb+UwASfw
> GVry3XJhobgNaH3xfDdx9h8S766k0B/JqtykK6fVbjoIJVxfnQ6yqz6w5604tjw1
> VdIyPwml4oAxOndQe0gxiAP5A7P8AyjAs0TvpRMILOm7gtE3tj4JM2ouFgK7VjY4
> aX8PGfoeKkazf4XJbuQSJXTODGikGLQSgnhmUz8Cd/MRKvnf4WCfaKl75JWPhl0=
> =yQIn
> -----END PGP SIGNATURE-----
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>

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}).

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.

However dialyzer (at least in 17.*) produces the following warnings:

myqueue_params.erl:10: Function new/0 has no local return
myqueue_params.erl:11: The attempt to match a term of type
myqueue:myqueue(integer()) against the variable _ breaks the opaqueness of
the term
myqueue_params.erl:14: Function in/2 has no local return
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

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.

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20141218/cf9874e8/attachment.htm>


More information about the erlang-questions mailing list