[erlang-questions] Indentation of multiline strings

Richard A. O'Keefe <>
Tue Feb 11 01:34:05 CET 2014


It is now more years than I care to recall since I wrote
the essay "Delenda est preprocessor."

It is extremely hard for indent(1) to do a good job of C.
Which is why it doesn't, really.

For example, here is some legal C code.

    if (border) printf("\\hline");
    rflag = border;
    for_each_element_child(e0, i, j, e1)
        printf(rflag ? "\\\\\n" : "\n");
        rflag = true;
        cflag = false;
        for_each_element_child(e1, k, l, e2)
            if (cflag) printf(" & ");
            cflag = true;
            walk_paragraph("", e2, "");
        end_each_element_child
    end_each_element_child
    if (border) printf("\\\\\\hline");

This is part of a program that turns slides marked up in SGML
into LaTeX.  It outputs the body of a table.

	for_each_element_child(Parent, I, J, Child)
	    <code for element children>
	if_no_element_child
	    <code for no elements>
	end_each_element_child

iterates over the children of Parent.  The variable I
counts all children.  The variable J counts those children
that are elements (as opposed to processing instructions,
comments, PCDATA, unresolved entity references, &c).  Child
is bound to the corresponding child.  Whenever such a Child
is for, <code for element children> is executed.  If Parent
has no child that is an element, <code for no elements> is
executed; that part is optional.

- If an indenter formats this with no knowledge of preprocessing,
  it will generate something unspeakably horrible.
- If an indenter is smart enough to look inside the macros, it
  will produce something that makes sense, but since
	- for_each_element_child has four left curly braces
	- if_no_element_child has }} if (...) {{
	- end_each_element child has four right curly braces
  the result will still not be something you want to read.
- Only if an indenter can be told about *these* macros specifically
  will anything reasonable happen.
- You really really REALLY do not want to do this stuff without
  such macros.  You don't want to see how

	for_each_descendant(Ancestor, Descendant)
	    <recursion without recursion>
	end_each_descendant

  is implemented.  You really don't.

In practice, this means that the tolerably large amount of code
I've written marching over SGML/XML documents -- and it may be
C, but it's *still* simpler than XSLT! -- *cannot* be indented
with indent(1) and still less can it be indented with emacs.

What is the relevance of this to Erlang?

Well, Erlang copied the C preprocessor, and must suffer the
consequences.

On 10/02/2014, at 8:01 PM, Bengt Kleberg wrote:

> Greetings,
> 
> One reason against a standalone formatter is that it could introduce
> bugs in the code. That this is only a problem with a standalone
> formatter is probably based upon that nobody would use a editor based
> formatter and then not compile/test after wards.

I do not believe that it IS "only a problem with a standalone
formatter" and I for one always check the output of indent(1).
> 
> To make a stand alone formatter with better level of confidence I
> suggest using Erlang/OTP tools to create one of the intermediate level
> formats (Core Erlang, "parse trees", the simplest/quickest/...) that
> removes formatting. If this is done before and after the standalone
> formatting, and the result is the same, then no bugs have been
> introduced.

I've always liked indenters that could cope with imperfect inputs.





More information about the erlang-questions mailing list