57 comments

[ 145 ms ] story [ 247 ms ] thread
I wish there we had an S-Expressions based alternative to Docbook for writing manuals and books. You can argue that DSSSL should have been preferred over XSL and friends but people seem to like verbosity even if the alternative (S-Expressions) is as precise and unambiguous.
Back when we were writing documentation in Docbook we just used a GUI editor like oXygen , so it did not matter.
I've been immersed in the markup world since the SGML days, and even I prefer s-expressions to SGML/XML.

But here's the thing: XML is all about agreement. The value is not found at the syntactic level, where needless irregularities exit. The value is that more than a critical mass of agreement formed, and this agreement allowed the development of tools and standards useful across industries. Moreover, the low-level agreement on XML has enabled higher level agreement on vocabularies and grammars in many disparate sectors.

Sure, if you had a clean slate you could improve many parts of the XML standards. Consider, for example, XML Schema (XSD). The irregularities and complexity there are similarly annoying. I'd much rather write RELAX schemas. However, whole sectors have selected XML Schema and developed vocabularies and grammars whose value isn't found at the syntactical level; it's found in the agreement reflected in the decisions over vocabulary and grammar made by disparate groups striving to develop a common exchange mechanism.

Quibbles over syntax miss XML's real merit: XML enables agreement in developing vocabularies and grammars.

Apropos: Here's my Stack Overflow answer to the question of when to use XML attributes vs elements, written in XML for fun: http://stackoverflow.com/a/23133755/290085

I don't mind the syntax and suppose I agree that consensus syntax is the right syntax.

The problem is beneath that: XML's semantics are tremendously large while also being a complete mess. The upshot is that the difficulty of being a compliant adopter---of matching such a large, nebulous, incompletely defined set of inconsistencies---is tremendous and instead there are leagues of partial, massively inconsistent consumers and producers who hammer out successful communication via a list of patches.

To some degree this situation was inevitable, but XML exacerbates it and cements the pattern.

Semantics has two senses that could apply here.

In one sense, XML itself is semantically neutral. The association between elements/attributes names and real world objects is merely suggestive.

In another sense (that of semantic analysis found in compiler design), validating XML parsers could be said to be enforcing semantics expressed in schemas. I suppose it is in this sense that your objection applies. In the case of XML Schemas or DTDs, I would have to agree. You might find RELAX NG to be less of a semantic mess given its basis in finite tree automata.

A majority of my concerns were resting on XML Schemas and the like—or even OWL (!)—but even recognizing what you mean about XML being semantically neutral it's still... semantically dangerous.

The issue at hand where attributes and elements can serve very similar purpose is a great example. In a technical sense XML does not suggest anything about the relative meaning of these two bits, but with near universal acclaim they're used as "metadata" and "child data" whatever the speaker might believe those to mean.

In spiritually embracing TIMTOWTDI, XML has created a playing field where semantics are by default ambiguous and have to fight their way out of that disadvantage.

In some sense, XML-without-semantics has too much structure and this creates a minefield for laying meaning atop it.

Someone's been confusing syntax and internal representation again.

Simple: parse

  <foo bar="zot">quux</foo>
as (JSON-like)

  { 
    "foo": {
       "bar" : "zot",
       "" : "quux"
     }
  }
Problem solved, XML is now logical again.
There is an existing alternative syntax for XML data [1] that represents it as a list of key-value pairs where the keys are XPath-like paths. In this syntax

  <foo bar="zot">quux</foo>
would be represented as

  /foo/@bar=zot
  /foo=quux
I think data serialization formats of this particular kind are underused. They are dead simple to parse while still being reasonably human-friendly (more so than XML, I'd say). Get rid of the attributes and introduce the convention that nodes with children named "0", "1", ... , "$N" are arrays and you can represent JSON.

[1] http://www.ofb.net/~egnor/xml2/

I like this, I had an instinct about making a file format similar to this, except pushing the path onto a stack.

<foo bar="zot"><baz>quux</baz></foo>

    [foo]
    @bar="zoot"
    
    [baz]
    "quux"
    
    []
    []
I figured you would save a little in the serialization. In practice I rarely need such a thing, and just serialize a structure to whatever I'm working with (s expressions, or in java xstream etc since those xml files are read somewhere...)
This does not do away the distinction between attributes and content -- that attributes are flat strings while content can be nested.
When you say that someone's been confusing syntax and internal representation, are you speaking of yourself? You don't parse XML as JSON, though you might parse XML and serialize the resulting internal representation as JSON. Also, XML is the syntactic representation of the document model, so your JSON isn't XML because it's a different sequence of characters.

That said, the JSON representation has a bug: what if there are multiple child elements? A fix would be using numeric indices for the children rather than the empty string. Then it would look both like an object with keys (attributes) and an array (of elements). Though, if you want to serialize that back into XML, you would need to make sure you never use non-strings as attribute values! Another bug is that the objects don't maintain their tag name; writing code to process data in this representation would be fairly annoying because a pointer to an element would be an object plus a key, rather than just an object. A fix for this would be to have a "tag" key inside the object.

I get terrible deja vu moments when I read Naggum's postings on the net. I knew him as a fellow student, long before I heard about his rants on the net and he actually had a very soft voice and spoke very calmly. Later I had the opprtunity to work with him professionally as well. He was a pleasure to have in meetings away from keyboard, but group discussions by e-mail could be very unpleasant.
That's actually why I like XML... the two-dimensional distinction between "metadata" and "content" can be really helpful... if and only if you need it. If you need it, then you are dealing with a fundamentally complicated format, and you will actually experience more pain trying to jam it into a single-dimensional format like JSON. By contrast, if the relevant data does not need the two dimensions, which is true of most things, XML is a terrible choice; left adrift without a meaningful way to distinguish between what should be "attribute" and what should be "content", both in theory and in practice all the choices turn out to be terrible.

And, again, if you really need it, the available third dimension provided by XML namespacing is a life-saver when you need it, and incredibly redundant when you don't.

I often dislike the phrase "Use the right tool for the job", because it is vacuous when not tied to some sort of suggestion on how you should determine what the right tool is, so: Match the dimensionality of your data to the dimensionality of the serialization format. The vast bulk of stuff you will encounter day-to-day is one dimensional and fits in JSON or a friend just fine. Use that. A nontrivial quantity of things fits into XML, mostly delimited text; use XML then. Every once in a while you need modularity in your XML format... do not reinvent XML namespaces, use them. (This is mostly for BIG standards, like XMPP or XHTML.) Use neither more nor less than what you need.

This reminds me of one of my biggest facepalm-ing moments when I first started using Lisp. I needed to serialise some data to disk, it was all in a list form - (list (a b) (c d)) kinda thing. So I thought to use XML format to store it on disk as that's what I had experience with in other languages.

I was about halfway through writing the (write-to-xml) function when I realised I could just write the entire lisp expression to the file instead...

Not only was it smaller, it had the huge advantage of not needing to parse it back when I wanted to read from disk, I just called the inbuilt (read) function. Thankfully I only wasted an afternoon!

That's what really ingrained the whole "data is code, code is data" idea into me. I even went on to write the structure function to each file as well, so that no matter what I did to the data structure down the line, I would still have the actual code needed to understand it. Right next to the data itself. Not only was my code self-documenting, my data was as well ;)

Why does everybody say it's lisp thing to save an expression to disc, or that "code is data in lisp" kind of things?

Every language I've ever used has variable assignment and you can write those to a document and execute it.

Because code is data is code in lisp. That's not the case in C or Java or C# or Rust or whatever.
I have never understood Erik's enduring appeal, particularly in light of the vehemence with which he could be technically wrong.

    <foo bar="zot">quux</foo>
    
      should be read as
    
    (foo (bar "zot") "quux")
    
      and most definitely _NOT_ as ((:foo :bar "zot") "quux")
Erik has this exactly backwards. His rendering is ambiguous: it does not distinguish <foo bar="zot"/> from <foo><bar>zot</bar></foo> (as he himself implicitly acknowledges later in the post). Also, rendering unqualified tags as keywords makes it easier to deal with namespaces.

IMHO the Right Way to render <foo bar="zot">quux</foo> is ((:foo :bar "zot") "quux") with the further qualification that if there are no tags then ((:foo) "quux") can be simplfied to (:foo "quux"). This preserves a 1-1 correspondence between XML and sexprs, which is IMHO a requirement (in fact, the only requirement) for a reasonable mapping. If you have a 1-1 correspondence then you can freely convert back and forth between the two. If you don't, then you can't.

> IMHO the Right Way to render <foo bar="zot">quux</foo> is ((:foo :bar "zot") "quux") with the further qualification that if there are no tags then ((:foo) "quux") can be simplfied to (:foo "quux").

Alternatively you could also write (foo ((bar "zot)) quux) as it is handled in Racket's X-expressions, which has the distinct advantage that the symbol/identifier foo is not nested one level deeper, which makes reading it harder, while still preserving the 1-1 correspondence. Though in this case the meta-information is the first argument instead of being part of the identifier. It also works perfectly with stuff like <foo bar="zot" baz="zor">quux</foo>, which is read as (foo ((bar zot) (baz zor)) quux). I personally think this is way better than ((:foo :bar "zot" :baz "zor) "quux")

> which has the distinct advantage that the symbol/identifier foo is not nested one level deeper

Why is that an advantage?

I actually like the aesthetics of the extra parens in the CAR. It provides a clear visual distinction between code and markup (at least in Common Lisp, where ((...) ...) is defined by the standard to be a syntax error) which I think is a feature. e.g.:

    ((:div :class "toplevel" :style "display:block")
     (:h1 "This is a heading")
     "This is content")
I think it looks kinda nice.
You've misunderstood his point with that example. He knows it's ambiguous, but he's telling you that it's an undesirable distinction to make.
OK, but then he's wrong about that. <input type=button/> does not mean the same thing as <input><type>button</type></input>.

No matter how you slice it, Erik is wrong here. His translation is lossy, and a lossy translation is bad because it can't be applied bidirectionally.

I believe his point was that what you are losing there does not really carry any extra information
Yes, I know that was his point. My claim is that he was wrong. The distinction does carry extra information. See my other comments in this thread for specific examples.
I think it's safe to say at this point that it is you who are dead wrong and not Erik.
Again, you're missing the point. He's saying that those two things shouldn't be different. He's clearly well aware that they are different.

His very first sentence is:

    As long as we think aloud in alternative syntaxes, I actually prefer to
    break the _incredibly_ stupid syntactic-only separation of elements and
    attribute values.
His entire post is a hypothetical in which you 1) need a structured markup language and 2) are willing to break compatibility with XML.
No, I understand what he is saying. My claim is that he is wrong. They should be different. There's a significant and useful difference between data and metadata, and hence there's a significant and useful difference between tags and attributes, and if you throw out that distinction you lose useful functionality, and specifically you lose the ability to distinguish between, e.g.:

<input type=button/>

and

<input><type>button</type></input>

Tags compose in different ways than attributes, that difference reflects a real aspect of the structure of the problem, and hence it's useful.

But it's not a difference between metadata and data. It's a difference between structural representations. Either or both representations can be used to encode data or metadata, but that separation comes from the interpretation of the markup.
Yes. But the two structures at issue are:

((foo baz bar) bing)

and

(foo (baz bar) bing)

The only difference is in the location of a single paren. But latter representation (Erik's) loses information whereas the former does not. All else being equal, and absent a compelling argument why the lost information has no value, it is better not to lose information.

1) There's no information to be lost. He's not talking about encoding XML, he's talking about general design criteria for a cleanroom markup language design. I don't understand why this point is hard to get.

2) The idea that it's "better not to lose information" is totally nonsensical because the value of information is contextual. For example, the ascii encoding of this message useful omits the subtleties of my awful handwriting, although you're right: it would be better to preserve the information present in the deep pencil strokes, indicating my frustrating with this thread.

> He's not talking about encoding XML

Yes he is:

"I have come to _loathe_ the half-assed hybrid that some XML-in-Lisp tools use and produce"

> The idea that it's "better not to lose information" is totally nonsensical

You are knocking down a straw man. I didn't say that is it better not to lose information, full stop. I said "All else being equal, and absent a compelling argument why the lost information has no value" it is better not to lose information. In the case of your handwriting, all else is not equal.

Erik Naggum even answererd the question about ambiguity himself in the same thread:

https://groups.google.com/d/msg/comp.lang.lisp/8eUxiibm_zA/i...

The essence of his response:

"Whether bar is an attribute or a sub-element of foo is irrelevant to processing them."

I disagree. Elements and attributes compose in different ways, and I think this distinction is useful and hence relevant. I think it is self-evident that:

<input type=button/>

and

<input><type>button</type></input>

mean different things, and that it is legitimate to try to express either of these things, and so distinguishing between these two different things is useful.

In particular, the latter representation implies that:

<input>foo</input> <type>bar</type>

might mean something. The former representation makes it explicit that the type attribute is intended to be inextricably bound to the input tag. I think that's useful information.

Did you just summarize thousands of sentences in a single one?

Neither <input type=button/> nor <input><type>button</type></input> does mean anything without a spec of your language, and trying to infer that <input>foo</input> or <type>bar</type> is valid is only due to some pre-conception about the underlying semantics you gave to your data (you chose familiar tag names, after all).

If I gave you a sample XML file from work, you'd have a very hard time knowing whether one attribute/element is or isn't optional (or bound) to an element. You'd need a schema/meta-model or even an informal spec.

With attributes/elements, you have two ways of defining data where only one is necessary: (input (type button)). The closet example I can think of is for example, if you had a lisp that is not homoiconic but had two different syntaxes for lists at its core: [] and (), without a simple way to abstract over them. Then your data format would be cumbersome to use with no added benefit: whether or not a []-list means something different than a ()-list depends on the specification of your data.

> Did you just summarize thousands of sentences in a single one?

Could be. The comment format demands a certain succinctness.

> Neither <input type=button/> nor <input><type>button</type></input> does mean anything without a spec of your language, and trying to infer that <input>foo</input> or <type>bar</type> is valid is only due to some pre-conception about the underlying semantics you gave to your data (you chose familiar tag names, after all).

Yes, that's true. Semantics is ultimately a very deep rabbit hole. My main claim is that it's useful to have an unambiguous syntactic distinction between data and metadata so that you can tell that the BAZ in <FOO BAZ=BAR>BING</FOO> is INTENDED to be a MODIFIER for FOO and NOT part of the CONTENT that FOO is marking up.

Actually, let me try to be excruciatingly precise: my claim is that it is not self-evident that a syntactic distinction between data and metadata is useless. Hence a rendering of XML into sexprs that preserves this distinction is defensible, and dismissing it in the pejorative terms that Erik uses is not justified.

Just as code is data and data is code, meta-data is another form of data. Erik' quotes are all taken from https://groups.google.com/d/msg/comp.lang.lisp/8eUxiibm_zA/C...:

> [...] is INTENDED to be a MODIFIER for FOO and NOT part of the CONTENT that FOO is marking up

"The intended use has less to do with it than the notion that you can define what is meta-information and what is information at the time you want to decide whether something goes in an attribute or a sub-element. My argument is that this is impossible. Whether it is meta-information or information is a reflection of the actual use, not the intended use.

However, given that the mechanism was created, and I will argue that it was not so much created as it was never thought possible to be any other way, it was used to define several language properties. "Now that we have this, would it not also be nice to have that." This means that several of the attribute types grew very far apart from the contents of sub-elements and you sort of "had" to use them as attributes, but only sort of, because the application can and does define the semantics of everything, and if you want ID and IDREF, you can make the same choice as you would in Common Lisp to use symbols or a hash tables of strings."

> Actually, let me try to be excruciatingly precise: my claim is that it is not self-evident that a syntactic distinction between data and metadata is useless. Hence a rendering of XML into sexprs that preserves this distinction is defensible, and dismissing it in the pejorative terms that Erik uses is not justified.

"No, there is nothing that requires there to be element attributes as a distinct concept from element contents. There are, however, a number of practical things that follow from making that arbitrar distinction which can look like rationales, but if you ask yourself "why can it not be a subelement", there are no real answers, only appeals to the idea that there somehow __have to be a distinction. It took me years to figure out that the whole attribute idea is completely vacuous, and I worked with the creator of SGML himself for several years on several SGML-related standards and projects. I started writing "A conceptual introduction to SGML" back in 1994, but as I had pained my way through five chapters, I had to realize that it was all wrong. There was a basic design mistake in the whole language framework. That mistake is that simply put: "what is good enough for the users of the language is not good enough for its creators". Each and every level of "containership" in SGML has its own syntax, optimized for the task. Each and every level has a different syntax for "the writing on the box" as opposed to "the contents of the box". This follows from a very simple, yet amazingly elusive principle in its design: Meta-data is conceptually incompatible with data. This is in fact wrong. Meta-data is only data viewed from a different angle, and vice versa. SGML forces you to remain loyal to your chosen angle of view."

So, the opinion seems to be that the arbitrary structure you put between meta-data and data at the moment you create data is not necessarly well-suited for people using your data: then, despite being useful, the syntactic distinction becomes an annoyance.

By the way, Erik's dissmissal is (1) the result of years of experience working on SGML, and (2) not pejorative, but argumented. He is the one arguing against the "self-evidence" of attributes.

> Erik's dissmissal is ... not pejorative

Sorry, the phrase "incredibly stupid" is pejorative.

And I don't really care if his position is the result of years of experience. It's wrong nonetheless. There are certainly stupid things in SGML, but the attribute/element distinction is not one of them. (Or at least, it's not a no-brainer that this is one of the stupid things in SGML, so if you're going to claim that the attribute/element distinction is stupid you need to provide a cogent argument to support your position and not just proclaim it as self-evidently true.)

It is absolutely not-ambiguous: Pairs in parentheses are attributes, everything after is values. He later introduces the || syntax to disambiguate: (foo (bar "zot")) vs (foo || (bar "zot")).

The <|> syntax is also absolutely non-ambiguous.

Well now, this is interesting. All of the other responses here have acknowledged that it is ambiguous (as Erik himself acknowledged) and argued that it should be ambiguous. And here you are saying the exact opposite: it is not ambiguous, the original rendering making it ambiguous is broken and needs to be fixed, and Erik fixes it by introducing new syntax (which, BTW, makes the new representation no longer an S expression).

It seems to me that the fact that people can't even agree whether he actually meant P or ~P ought to call his wisdom (or at least his ability to communicate) into question.

Erik clearly states that he thinks the attribute/element distinction is "_incredibly_ stupid," and while he does give an example of an expression which combined the two, he does not neglect to call it "pathological."

I'm fairly certain that the reason he handles the pathological cases is so that he may interface with other people's XML specs. One can hate the design while meaningfully working with others, right?

By the way, it is an S expression. He uses the empty symbol || as a delimiter for the pathological cases. Furthermore, the Enamel syntax he describes is a reader macro; whether you think that is OK is up to your own personal aesthetics, but it is just an alternative syntax for lists (not everything has to syntactically be an S-expression, after all).

You (lisper) keep mentioning that there is a distinction between metadata and data, and you mention that composibility is the big distinction. However, as far as I can tell, you can compose child elements in an ordered sequence which you can't do with attributes (though you can append sets of attributes as sets), and you can't nest attributes. It seems to me that the only reason for everything not to be elements is that they take longer to type with XML syntax. Also, child elements are in some sense just attributes with implicit numeric keys, if attributes could be data other than strings.

What is an example of this distinction between attributes and elements which is not just syntax?

> Erik clearly states that he thinks the attribute/element distinction is "_incredibly_ stupid,"

Yes. And I'm saying he's wrong. Not only is he wrong, he's clearly wrong. Not only is it not "incredibly stupid", the distinction between attributes and elements is both reasonable and useful. And the reason it's reasonable and useful is because it reflects a reasonable and useful distinction between data and metadata.

> What is an example of this distinction between attributes and elements which is not just syntax?

I don't understand that question.

My claim is that, in the context of markup languages, there is a useful distinction to be made between data and metadata, and that this distinction is useful enough that it is not unreasonable to make this distinction syntactically. Of course, it doesn't have to be made syntactically. In Lisp, there is no syntactic difference between function calls and control constructs. Consider:

(foo (baz bar) bing)

Is (bar bar) a function call? If FOO is a macro that expands to:

(dotimes (baz bar) bing)

then BAZ is a variable binding. Arguably, it would be worthwhile to make a syntactic distinction here. For example, you could use square brackets for variable bindings, so that you could tell that in:

(foo [baz bar] bing)

BAZ was a variable binding without having to know how FOO was defined. It's not a slam dunk, but it is a defensible position.

Likewise, it is a defensible position that the difference between <foo baz=bar>bing</foo> and <foo><baz>bar</baz></foo> -- whatever that difference might actually be in practice -- is valuable and ought to be preserved. Again, not a slam-dunk, but a defensible position.

What makes Erik clearly wrong is this his rendering of <foo baz=bar>bing</foo> is NOT actually any simpler than a rendering that preserves the attribute/element distinction. His rendering has EXACTLY the same level of nesting, the same number of tokens. The ONLY difference is the location of a paren. And the way he moves the paren, he loses information. Without a compelling argument why moving that paren has more value than the information that he loses, that paren ought not to be moved. All else being equal (and in this case all else is equal) it is better to keep information than to lose it. Not only does Erik not make a compelling argument, he makes no argument at all. He simply proclaims that it is "incredibly stupid" and his acolytes, for reasons passing my comprehension, agree.

> Not only is he wrong, he's clearly wrong.

You keep repeating that, but the more you discuss it, the less "clear" it is.

> I don't understand your question.

You acknowleded that we need to have a specification in order to make sense from a piece of markup. When we know what elements are to be expected in a format, what "clear" and "useful" advantage gives an additional arbitrary syntactic separatation over a sub-element-only layout? and why is it more "reasonnable" to have this separation when it actually make it slightly more difficult to manipulate the data?

> My claim is that, in the context of markup languages, there is a useful distinction to be made between data and metadata, ...

Originally, attributes made sense "in the context of markup languages" because attributes were metadata and sub-elements where "content". This is a reason why Naggum was first favorable for the distinction. But then the line was blurred, because not everything is so simple and you find attributes that refer to "data" (title attribute) and sub-elements that refer to "meta-data" (<meta> tag, for example).

> (foo [baz bar] bind) > ... you could tell that ... BAZ was a variable binding without having to know how FOO was defined. It's not a slam dunk, but it is a defensible position.

You don't need to know how FOO was defined, but you have a contract with FOO: there are many other distinctions one could make (not only bindings/parameters): will you invent a new syntax for everyone of them? Is that really useful? XML is used when you don't want to have a complex syntax and when a standard AST suffice. And then, attributes are an added complexity with little benefits.

> what "clear" and "useful" advantage gives an additional arbitrary syntactic separatation over a sub-element-only layout?

It syntactically distinguishes information that applies to the tag from information to which the tag applies.

> why is it more "reasonnable" to have this separation when it actually make it slightly more difficult to manipulate the data?

It's a tradeoff, of course. Reasonable people can disagree about whether the tradeoff is worth it. But that's my point: reasonable people can disagree.

> But then the line was blurred

Any language feature can be abused. The proper response IMO is to stop abusing the feature, not to eliminate it.

> will you invent a new syntax for everyone of them?

I don't know. What other kinds of distinctions did you have in mind?

> attributes are an added complexity with little benefits

I understand that you believe this. Do you see how a reasonable person might disagree?

> It's a tradeoff, of course.

> Reasonable people can disagree about whether the tradeoff is worth it.

> But that's my point: reasonable people can disagree.

Sure, we disagree. I understand that you think there is a tradeoff, like in many design decisions. However, you did not tell me what benefits you expect from having the syntactical distinction.

> It syntactically distinguishes information that applies to the tag from information to which the tag applies.

That statement alone does not say why it is a good thing to distinguish syntactically both kind of informations. This looks interesting, of course, to be able to have a distinction. The fact that there is a distinction on the semantical level does not mean it should be there syntactically, though.

The syntax for attributes is unfortunately flawed, which is why ...

> Any language feature can be abused. The proper response IMO is to stop abusing the feature, not to eliminate it.

... is taking the problem completely backwards. No language feature were abused. In fact, attributes were acting against a natural organization of information. And that is why, as a workaround, it was needed to express meta-data with tags. I don't expect you to agree with this, so consider a classical example of markup usage.

You want to represent a document, with reviewers, publication dates and authors (those are meta-informations, right?) as well as content (the actual text being stored). However, there exists meta-informations about people (name, title) and dates (calendar). Where do we store structured meta-informations about attributes?

Unfortunately, attributes do not allow to express structured information, and they cannot have meta-informations attached to them. Here is what you obtain:

     <root>      
          <document author="id0"
                    published_in="ACM"
                    publication_date="2010/03/02"
                    publication_volume=345
                    link="doi://1020301.202.301.1023"
                    reviewers_id="id1;id2;id3;id4">

            ... content ...

          </document>

          <peoples>
            <people id="id0"><name>John Doe</name>...</people>
            <people id="id1">...</people>
            <people id="id2">...</people>
            <people id="id3">...</people>
            <people id="id4">...</people>
          </peoples>
     <root>     

Notice how informations about publication are scattered into different attributes instead of being a single attributes with sub-components? (has the document been published in March or February? In which timezeone?)

Authors are only indirectly referenced through identifiers, because the real structure cannot be easily expressed in attributes only. Also, a list of reviewers is actually a string with semicolon-separated identifiers.

An so, peoples are not just meta-informations, but tags with nested children and you must have a "root" element around your document, and a special list of "peoples". Just to be clear, having identifiers is not bad and could be a good way to model relationships. The problem is that you do not have a choice anymore of using different level of meta-attributes.

Notice how the link to a "DOI" identifier is itself encoded in a string (this is a custom format just for this example), instead of using a more useful nested structure:

       (link (protocol doi)
             (path (digits 1020301 202 301 1023)))

Each time you use a string to encode structured information in an attribute with a custom mini-language, you are asking for trouble. Imagine how each of those strings now need to have a dedicated parser because you need to take care ...
> I really do not see anything useful in having attributes

That's because you chose examples that show attributes at their worst.

Suppose that instead of a document with a single author you instead had a document to which many people contributed, and you wanted to mark it up to show who wrote which section. Using attributes (and identifiers) you would have, e.g.

    <author id=Bob>[info about Bob]</author>
    <author id=Alice>[info about Alice]</author>
    <span author=Bob>This part was written by Bob</span>
    <span author=Alice>and this part was written by Alice</span>
    <span author=Bob>and this part was written by Bob again.</span>
This example also highlights why it is sometimes NECESSARY to use identifiers in order to produce the semantically correct structure. Suppose you put all the author information in-line as you suggest. The result would look something like this:

    <span><author><name>Bob</name>[info about Bob]</author>This part was written by Bob</span>
    <span><author><name>Alice</name>[info about Alice]</author>This part was written by Alice</span>
    <span><author><name>Bob</name>[info about Bob]</author>This part was written by Bob</span>
Were the first and third parts written by the same person, or by two different people whose names both happen to be Bob? If you put everything in-line there is no way to express that two pieces of structure are intended to be EQ to each other.
Did you not read my reply, really?

I already mentionned that with a Lisp like data-format, shared sub-expressions could be denoted using CL's reader variables:

      (document
        #1=(author (id "Bob") ... )
        #2=(author (id "Alice") ... )
        (span (author #1#) "written by Bob")
        (span (author #2#) "written by Alice")
        (span (author #1#) "written by Bob"))
I do not claim that this is the most appropriate solution in all cases, just that we are not forced to introduce indirection levels when unnecessary. Now, if I am using Lisp and I want to introduce external references to authors described in other documents, I could introduce a meta-data with an appropriate semantical structure:

       (external-element (pathname (directory (relative "path" "to")) 
                                   (type "lisp")
                                   (name "file")) 
                         (tree-path 2 1 3 2 2 3))
This would be a practical way to encode a precise location in a tree in an external file. And I could use this form everywhere I need to reference an object. Also, the tree-path notation is handy because there is no distinction between an attribute or an element, just which branch to take at each step from the root.

Now, with XML attributes, I would typically have an "xref" attribute. How can we model xref attributes? If we wanted to have structured data, we would need to create external tags with the same concepts as above, like <pathname>, create a local identifier for each xref and refer indirectly to each xref using their local identifier: because we can only put strings. I mean:

     <author xref="xref02"> 
     ...
     <xref id="xref02">
       <pathname> ... </pathname>
       <tree-path> ... </tree-path>
     </xref>
Or, we do as everybody and encode it like for XMI, or ECORE, or any other custom format, with a complex string, hoping that HTML entities are properly escaped.

Besides, you failed to notice that you had <author> tags, which precisely goes against your idea that there should be a place for "meta-data" and a place for "data": effectively, authors are now part of the content of the document, and are not only meta-informations.

If you think my examples are artificial, open the source code of this page, and observe how any kind of complex information written in attributes has to be properly escaped to bypass the limitation of stringly-typed data:

       reply?id=9556252&amp;goto=item%3Fid%3D9555880"

       href="vote?for=9556252&amp;dir=up&amp;auth=0UU000REDACTED000208d8b9f4a45575b4edea3779&amp;goto=item%3Fid%3D9555880"
Notice how you need to escape HTML entities in inline javascript attributes (onclick) but not on script tags. Why are inline javascript not tags instead?

(see http://stackoverflow.com/questions/8749001/escaping-html-ent...).

Whatever example you choose, you cannot deny the fact that attributes are not given the same rights as elements, because the way they do not allow to contain structured data or cannot have meta-attributes themselves.

> Did you not read my reply, really?

I did read it.

> I already mentionned that with a Lisp like data-format, shared sub-expressions could be denoted using CL's reader variables:

Yes, of course this is possible. But that's just a different way of implementing tags (and not even a very good one either because your tags are constrained to be numeric).

> we are not forced to introduce indirection levels when unnecessary

That's a tautology.

> I could use this form everywhere I need to reference an object.

Of course you could. Most problems have more than one reasonable solution. But pointing out one reasonable solution is irrelevant to the question of whether a different solution is also reasonable.

> your idea that there should be a place for "meta-data" and a place for "data"

That wasn't exactly my idea. What I said was that there was value in having a syntactic distinction between data and meta-data. But I didn't say that this distinction should be universal. In fact it is impossible to distinguish between data and metadata in general, so you can always come up with examples where a particular datum's role is ambiguous. That doesn't change the fact that in many practical circumstances, having a syntactic distinction is appropriate and useful.

> observe how any kind of complex information written in attributes has to be properly escaped

Again, citing circumstances where things fall apart does not change the fact that in many practical circumstances, having a syntactic distinction between data and meta-data is appropriate and useful.

If you choose to reply to this, please remember: I'm a Lisp fan. (Look at my HN user ID!) I hate XML. I much prefer S expressions. When I have to deal with XML, the first thing I do is parse it into S-expressions. The world would be a better place if everything were S-exprs no one used SGML or any of its devil spawn syntaxes. But that's not the world we live in. In the world we live in, where markup languages exist and are required to have matching end tags, attributes are a defensible design.

I think the confusion here (not yours specifically) is that his actual <|> syntax resolves this ambiguity and his informal CL translation does not.

You are correct that:

  <foo bar="zot">quux</foo>  =>  (foo (bar "zot"))
  <foo><bar>zot</bar></foo>  =>  (foo (bar "zot"))
Is an ambiguity. However in his <|> syntax:

  <foo bar="zot">quux</foo>  =>  <foo <bar | "zot">>
  <foo><bar>zot</bar></foo>  =>  <foo | <bar | "zot">>
What about, say:

  <foo bar="zot">quux</foo>
as

  (foo (bar "zot") (data "quux"))
Or any other keyword which you could reserve as being the special "non-meta" data?

  (foo (bar "zot")) is then unambiguously <foo bar="zot"/>
  (foo (data (bar "zot"))) is then <foo><bar>zot</bar></foo>
I'm not sure whose side I'm on by proposing this. I'd be interested to know.
Sure, there are lots of ways of restoring the lost information. My point is just that Erik opens by claiming emphatically (AFAICT -- people seem to disagree about this) that this information SHOULD NOT be restored, that it is WRONG to try to make a syntactic distinction between data and metadata in a markup language:

"Whether something is an attribute or element is _completely_ arbitrary."

THAT is the point on which he is (IMHO) clearly wrong. (He's wrong about a bunch of other things too, but that's the most serious mistake.)

EDIT: Here is Erik doubling down on his position:

"I have a simple way to get rid of the annoying verbosity of these stupid languages while _retaining_ that mistake [sic] between attribute values and elements"

I interpreted him as saying (and it sounds like you may have as well?) that this distinction SHOULD NOT be ENCODED in XML or S-Expression or whatever data serialization/markup syntax you invent.

He does not appear to make an argument as to why he believes this, so I'd say his claim is at worst unsubstantiated.

I find it hard to believe that there's a objectively correct decision about the number of semantic concepts that "should" be encoded in a syntax, but I can understand why lisp enthusiasts would be on the 'closer-to-none end of that spectrum.

I'd be interested to hear why you think it's so essential. The only argument I'm really aware of is compatibility with existing markup languages.

I would guess that a markup syntax that is as simple and regular (ie. syntactically consistent) as possible would be the easiest to operate on algorithmically. I would also guess that this would make it easier to build, on top of this language, tools which present the content in various ways that are easier to read/write/manually-manipulate if you so desired.

Actually, his example syntax makes this argument implicitly. He is suggesting that his tools are significantly easier to implement by working with plain S-Expressions, and that they can easily be mapped to a 'write-friendly markup language that is isomorphic to XML anyway.

I make no claims about the quality of his presentation or the clarity of his arguments.

Where did he copy and misunderstand this from?
I'm not even sure why we're discussing this when the post is mostly a strawman. There isn't any example given for "what makes it so goddamn hard to reason about SGML documents". If I understand the idea, he is suggesting that

  <foo bar="zot">quux</foo>
is the same as

  <foo bar="zot" text="quux"/>
or

  <foo><bar>zot</bar>quux</foo>
The ambiguity is introduced when you suggest that meta-information and information are the same thing. Clearly, we wouldn't say that context is the same as experience or that memory is the same as reality.

Meta-information and information can be used in different ways to express or define the document which is why it would be better to understand the original complaint. The syntax exists because the distinction is useful for simple things like separating style from content (as others have mentioned). When there is ambiguity about the nature or value of the meta-information, it has nothing to do with the syntax. For example:

  <apply>
    <in/>
    <cn type="complex-cartesian">17<sep/>29</cn>
    <complexes/>
  </apply>
does a pretty poor job of conveying the information and the distinction between the element "complexes" and the attribute "type" is not readily understood. But let's not throw out the baby with the bathwater and suggest that the distinction is stupid when clearly the universe presented you with an absurdity.
The LISP code there doesn't make things clearer IMO but I agree completely with his point that the attribute and content rules add huge unneeded complexity to XML.

Really enjoy these types of articles on markup languages. If there are any other markup language nerds out there I've been chipping away at a simple one (https://github.com/breck7/space), and would love feedback. And if you have one as well always love looking at different ideas.