<div dir="ltr"><div>There are some distinctions that have not been well documented. I'll try to clarify them based on how things actually work.</div><div><br></div><div>First, an Erlang program is divided into "forms" - sequences of tokens that are terminated by a full stop. Forms are either function definitions (starting with a function name, i.e., an atom) or what's generally called "attributes", which start with a minus and an atom, as in '-module(..).'. Seems straightforward, right?</div><div><br>There are however three kinds of forms in Erlang that have the general shape of attributes:</div><div><br></div><div>* Preprocessor Directives - things like '-include("foo.hrl").' or '-ifdef(DEBUG)'. These only make sense to the preprocessor (epp), and are removed by the preprocessing step.</div><div><br></div><div>* Declarations - things like module name, export/import lists, record definitions, type specifications, type definitions, and behaviour callbacks. Also some more unknown special declarations like '-file(...).' that the preprocessor inserts to tell the compiler which parts of the code came from which files, or errors and warnings passed on from preprocessing. The common thing about Declarations is that they have meaning on the Erlang Language level, and typically have particular rules for how they may look (a module declaration must provide a single module name, an import declaration must provide a module name and a list of function/arity pairs, a record declaration must list fields and possibly types, and so on), and where in the file they may occur (before any function, or interspersed with functions). Since these are part of the language, they are not included in the 'attributes' list of the Beam file; the corresponding information is generally found in some other part of the file.</div><div><br></div><div>* "Wild" Attributes (as they were named in the draft Standard Erlang specification) - any attribute that is not one of the Declarations, and has the form '-Atom(Term)' - note that only one argument is allowed. These can occur anywhere in the file and have no special meaning except possibly to various tools. For example, '-compile(Options).' only has a meaning to the specific Erlang compiler that you're using; it's not part of the language. These are just annotations, and these are the ones that are listed in the 'attributes' section of the module info.</div><div><br></div><div>These distinctions have not been properly documented, but have been intuitively followed by the people working on the language and compiler. In some cases, the lines are blurred. For example, one could easily argue that '-behaviour(Name).'  was just another wild attribute which only had a meaning to the current version of the compiler, and not part of the language proper. On the other hand, since the -callback declarations were introduced, it's pretty clear that behaviours are a language feature.</div><div class="gmail_extra"><div><div class="gmail_signature" data-smartmail="gmail_signature"><br></div><div class="gmail_signature" data-smartmail="gmail_signature">Along these lines, I think that e.g. the type declarations of a module should be included in Beam files as standard chunks, so you don't need to extract them from the "abstract format" debug information, if present, but that's another can of pull requests.</div><div class="gmail_signature" data-smartmail="gmail_signature"><br>        /Richard</div></div>
<br><div class="gmail_quote">2017-01-24 4:04 GMT+01:00 Ryan Stewart <span dir="ltr"><<a href="mailto:zzantozz@gmail.com" target="_blank">zzantozz@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><span class=""><div dir="ltr">On Mon, Jan 23, 2017 at 6:28 AM Björn Gustavsson <<a href="mailto:bjorn@erlang.org" target="_blank">bjorn@erlang.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The change was intentional, but we did not foresee that it would<br class="m_6264585536061060879gmail_msg">
cause problems.<br class="m_6264585536061060879gmail_msg">
<br class="m_6264585536061060879gmail_msg">
There is no formal documentation exactly which attributes should<br class="m_6264585536061060879gmail_msg">
appear in module_info(attributes). A long time ago, all attributes<br class="m_6264585536061060879gmail_msg">
except 'module', 'export', 'import', 'file', and 'record' were included.<br class="m_6264585536061060879gmail_msg">
<br class="m_6264585536061060879gmail_msg"></blockquote></span><div>Well, to that point, the following appears on the Modules reference page (<a href="http://erlang.org/doc/reference_manual/modules.html" target="_blank">http://erlang.org/doc/<wbr>reference_manual/modules.html</a>)<wbr>:</div><div><br></div><div>"Any module attribute can be specified. The attributes are stored in the compiled code and can be retrieved by calling Module:module_info(attributes)<wbr>, or by using the module beam_lib(3) in STDLIB."</div><div><br></div><div>The most straightforward understanding of that has to be that all attributes are equally accessible in both places.</div><span class=""><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
When the dialyzer attributes 'type', 'spec', and 'opaque' were introduced<br class="m_6264585536061060879gmail_msg">
we decided not to include them to reduce the code size.<br class="m_6264585536061060879gmail_msg">
<br class="m_6264585536061060879gmail_msg">
Since 'callback' and 'optional_callback' are attributes that<br class="m_6264585536061060879gmail_msg">
are used by dialyzer, we decided that they too should be<br class="m_6264585536061060879gmail_msg">
excluded (for consistency).<br class="m_6264585536061060879gmail_msg">
<br class="m_6264585536061060879gmail_msg"></blockquote></span><div>That makes sense in a way, but at the same time, it seems very odd for all of these things to be "attributes", and yet only some of them appear when you ask the language for the attributes of a module. Regardless of the intended use of an attribute, why would the platform lie about whether or not an attribute is present?</div><div><br></div><div>Also, what do you mean by "excluded"? As I pointed out in my post, the attributes are still present in the abstract code. I don't understand what's saved by having them in one place but not the other.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>Ryan</div></font></span></div></div>
<br>______________________________<wbr>_________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer" target="_blank">http://erlang.org/mailman/<wbr>listinfo/erlang-questions</a><br>
<br></blockquote></div><br></div></div>