<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014 Apr 18, at 12:00 , Loïc Hoguin <<a href="mailto:essen@ninenines.eu">essen@ninenines.eu</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">On 04/18/2014 11:55 AM, Dániel Szoboszlay wrote:<br><blockquote type="cite">Hi,<br><br>I’d recommend you to decouple the type spec from the record the<br>following way:<br><br>-record(kv, {key, value}).<br>-type kv() :: #kv{key::string(), value::integer()}.<br><br>Bonus feature: you can export the kv/0 type from your module (if you<br>need to), but you can’t do that when the types are embedded into the<br>record declaration.<br></blockquote><br>I am not sure what you mean by that. I have been doing it for a long time and it works just fine, albeit I always use opaque for exported records.<br></blockquote><div><br></div><div>Well, sometimes two modules need to use the same record (defined in a header of course). Then you can do something like:</div><div><br></div><div><font face="Menlo">-module(foo).</font></div><div><font face="Menlo">-include(“foorec.hrl”).</font></div><div><font face="Menlo">-type foorec() :: #foorec{…}.</font></div><div><font face="Menlo">-export_type([foorec/0]).</font></div><div><font face="Menlo">…</font></div><div><font face="Menlo"><br></font></div><div><div><font face="Menlo">-module(bar).</font></div><div><font face="Menlo">-include(“foorec.hrl”).</font></div><div><font face="Menlo">-spec bar(Foo :: foo:foorec()) -> ok.</font></div><div><font face="Menlo">…</font></div><div><br></div></div><div>I like this pattern, because it’s easy to understand who is responsible for the foorec() type, the type spec will end up in the EDoc page and so on.</div><div><br></div><div>Anyway, that’s not so important for the original question. What is important is that by separating record declarations from type specs you can clearly explain to Dialyzer via function specs when do you want to deal with a type-correct record and when do you just happen to handle tuples that look like your records (e.g. in match specs or by a random coincidence like in this <a href="http://erlang.org/pipermail/erlang-questions/2013-June/074117.html">other question</a>).</div><div><br></div><div>Regards,</div><div>Daniel</div></div></body></html>