<div dir="ltr">1. As I understand underspec and overspec requires precise indication of types. <div>So for a list of a,b,c atoms you _must_ indicate [a,b,c] but not just a list of atoms. </div><div>Because list of atoms implies a list of any size with any atoms not a list of 3 specific atoms a,b,c.<br><br>2. The only possible reason why proplists:proplist "works" is that the dialyzer </div><div>doesn't know about this type and it is kinda silent in such cases. Try -Wunknown option.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">пн, 17 мая 2021 г. в 23:25, Paulo Zulato <<a href="mailto:paulozulato@gmail.com">paulozulato@gmail.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hello,</div><div><br></div><div>I'm trying to figure out why dialyzer is complaining about a function when I don't explicitly declare its return as a proplist.<br></div><div>I have this small module which returns a proplist in the form <span style="font-family:monospace">{atom(), [atom()]}</span>:</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span style="font-family:monospace"><span style="color:rgb(178,104,24);background-color:rgb(255,255,255)">-module</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">(</span><span style="color:rgb(178,24,24);background-color:rgb(255,255,255)">test</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">).
</span></span><br><span style="font-family:monospace">
</span><br><span style="font-family:monospace"><span style="color:rgb(178,104,24);background-color:rgb(255,255,255)">-export</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">(</span><span style="color:rgb(178,24,178);background-color:rgb(255,255,255)">[</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">test</span><span style="color:rgb(178,104,24);background-color:rgb(255,255,255)">/</span><span style="color:rgb(178,24,24);background-color:rgb(255,255,255)">0</span><span style="color:rgb(178,24,178);background-color:rgb(255,255,255)">]</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">).
</span></span><br><span style="font-family:monospace">
test() <span style="color:rgb(178,104,24);background-color:rgb(255,255,255)">-></span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)"> </span></span><br><span style="font-family:monospace"> <span style="color:rgb(178,24,178);background-color:rgb(255,255,255)">[</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)"> </span></span><br><span style="font-family:monospace"> <span style="color:rgb(178,24,178);background-color:rgb(255,255,255)">{</span><span style="color:rgb(178,24,24);background-color:rgb(255,255,255)">one_test</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">, </span><span style="color:rgb(178,24,178);background-color:rgb(255,255,255)">[</span><span style="color:rgb(178,24,24);background-color:rgb(255,255,255)">a</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">,</span><span style="color:rgb(178,24,24);background-color:rgb(255,255,255)">b</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">,</span><span style="color:rgb(178,24,24);background-color:rgb(255,255,255)">c</span><span style="color:rgb(178,24,178);background-color:rgb(255,255,255)">]}</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">,
</span></span><br><span style="font-family:monospace"> <span style="color:rgb(178,24,178);background-color:rgb(255,255,255)">{</span><span style="color:rgb(178,24,24);background-color:rgb(255,255,255)">another_test</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">, </span><span style="color:rgb(178,24,178);background-color:rgb(255,255,255)">[</span><span style="color:rgb(178,24,24);background-color:rgb(255,255,255)">d</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">,</span><span style="color:rgb(178,24,24);background-color:rgb(255,255,255)">e</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">,</span><span style="color:rgb(178,24,24);background-color:rgb(255,255,255)">f</span><span style="color:rgb(178,24,178);background-color:rgb(255,255,255)">]}</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
</span></span><br><span style="font-family:monospace"> <span style="color:rgb(178,24,178);background-color:rgb(255,255,255)">]</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">.</span></span><br><span style="font-family:monospace"></span></blockquote><br><div>For function above, I made the following spec, but dialyzer has complained (as stated below) when I enabled its underspecs warnings<span style="font-family:monospace"><span style="color:rgb(0,0,0);background-color:rgb(24,178,178)"></span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">.</span><br></span></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span style="font-family:monospace">-spec test() -> [{atom(), [atom()]}].</span><br><span style="font-family:monospace">% src/test.erl</span><br><span style="font-family:monospace">% Type specification test:test() -> [{atom(),[atom()]}] is a supertype of the success typing: test:test() -> [{'another_test',['d' | 'e' | 'f',...]} | {'one_test',['a' | 'b' | 'c',...]},...]</span><br><span style="font-family:monospace"></span></blockquote><div><br></div><div>Well... both lists are non-empty lists as stated by dialyzer, so I modified the spec, without success:<br></div><div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span style="font-family:monospace">-spec test() -> [{atom(), [atom(), ...]}, ...].<br>%src/test.erl<br>% Type specification test:test() -> [{atom(),[atom(),...]},...] is a supertype of the success typing: test:test() -> [{'another_test',['d' | 'e' | 'f',...]} | {'one_test',['a' | 'b' | 'c',...]},...]<br></span></blockquote><div><br></div><div>Then I tried to explicitly declare it as a proplist, and dialyzer has accepted it:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span style="font-family:monospace">-spec test() -> proplists:proplist().<br></span><div><span style="font-family:monospace">% OK, no warnings.</span></div></blockquote><div><br></div><div>As it worked, I tried to do the same as proplists module does and created two types, which I used on my new spec. And, surprisingly, dialyzer has complained about it! <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><span style="font-family:monospace">% From <<a href="https://erlang.org/doc/man/proplists.html" target="_blank">https://erlang.org/doc/man/proplists.html</a>><br></span></div><div><span style="font-family:monospace">-type property() :: atom() | tuple().<br>-type proplist() :: [property()]. <br></span></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><span style="font-family:monospace"><br>-spec test() -> proplist().<br>%src/test.erl <br></span></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><span style="font-family:monospace">% Type specification test:test() -> proplist() is a supertype of the success typing: test:test() -> [{'another_test',['d' | 'e' | 'f',...]} | {'one_test',['a' | 'b' | 'c',...]},...]</span><br></div></blockquote><br><div></div><div></div><div>Therefore, I could not understand why declaring the return as "proplists:proplist" is OK while declaring it as lists, nonempty lists or creating the same types as proplists are not OK. Why is dialyzer complaining about the other specs? Is dialyzer handling proplists in a different way? Could someone help me to understand this behaviour?<br></div><div><br></div><div><br></div><div>Best Regards,</div><div><div><div><div dir="ltr">Paulo Zulato<br><br>--<br>«Quis custodiet ipsos custodes?»</div></div></div></div></div>
</blockquote></div>