Why Layout Matters
I have found myself reading Adobe’s AMF3 specification, and trying to read their ABNF grammar for AMF3. Unfortunately, Adobe have seen fit to format their nesting in arbitrary ways that make it hard to read. Here are two examples from the specification (which has not been touched since 2008, to the best of my knowledge):
array-type = array-marker (U29O-ref | (U29A-value (UTF-8-empty | *(assoc-value) UTF-8-empty) *(value-type))) ... object-type = object-marker (U29O-ref | (U29O-traits-ext class-name *(U8)) | U29O-traits-ref | (U29O- traits class-name *(UTF-8-vr))) *(value-type) *(dynamic-member)))
Line breaks in arbitrary places do not make the ABNF any easier to read. (Line breaks in the middle of a terminal are also in poor taste.) If you count the parentheses in the object-type definition, you will find that there are two extra closing parentheses. This is not optimal for a grammar for a binary language that is supposed to enable interoperation.
If the specification authors had used logical layout, this would have been completely obvious:
array-type = array-marker (U29O-ref | (U29A-value (UTF-8-empty | *(assoc-value) UTF-8-empty) *(value-type))) ... object-type = object-marker (U29O-ref | (U29O-traits-ext class-name *(U8)) | U29O-traits-ref | (U29O-traits class-name *(UTF-8-vr)) ) *(value-type) *(dynamic-member) ))
I guess it should surprise no one that a long-time Python programmer would suggest that literal layout influences both readability and comprehensibility.
I guess I should also rant that the specification says that the grammar is specified in Augmented Backus-Naur Form, and explicitly references RFC2234 (since obsoleted by RFC4234, then by RFC5234), but then uses the vertical bar character | when RFC2234 clearly states that alternatives will be presented with a solidus (forward slash) /. However, we’re all used to | from BNF and EBNF, so I can forgive that more easily…