S-Expressions: The Fat-Free Alternative to JSON

JSON is a data description language based on the JavaScript object literal syntax. It is designed to express more information in less typing (than XML). For example:

<person>
  <name>
    <first>John</first>
    <last>Smith</last>
  </name>
  <age>25</age>
</person>

JSON, is designed to be more lightweight than XML:

{
  'name': ['John', 'Smith'],
  'age': 25
}

However, JSON is not good at document markups:

<p>Paragraph text here, <b>bold text</b></p>

vs.

{ 'format': 'paragraph', ['Paragraph text here, ', {'format': 'bold', body: ['bold text']}] }

JSON becomes verbose when dealing with non-key-value-pair data structures.

Introducing S(ymbolic)-Expressions, S-expressions are originated from the Lisp programming language to describe data structures and programs. They describe list-like data structures:

(person (name John Smith) (age 25))

A list is enclosed by parenthesis, and the list elements are separated by whitespaces. The primitive datatypes varies from specification to specification. http://people.csail.mit.edu/rivest/Sexp.txt is the spec I am going to use. That spec introduces syntaxes for data encoding such as length-prefixed strings (like 4:this), base64 strings, hex strings and conventional quoted strings.

Here are some S-Expression examples:

(if (> x 3) (+ 2 (* x 3)) (/ 2 x))
(1 2 (3 4) 5 (6 (7 8)))
(11:certificate(6:issuer3:bob)(7:subject5:alice))
(certificate (issuer bob) (subject alice))
(p "Paragraph text here, " (b "bold text"))

XML schemas are complicated, JSON schemas are easier, and S-expression schemas can be simpler than ever. Think of how Haskell tagged unions work.

data Expr = Add Expr Expr | Sub Expr Expr | Mul Expr Expr | Div Expr Expr | Const Int
(schema (root expr)
  (pattern expr
    (oneof
      (add :expr :expr)
      (sub :expr :expr)
      (mul :expr :expr)
      (div :expr :expr)
      :integer
      :variable
    )
  )
  (pattern integer (regexp "(\d+)"))
  (pattern variable (regexp "([A-Za-z]+)"))
)

which validates

(div (sub (mul 2 x) 3))


17 Responses to “S-Expressions: The Fat-Free Alternative to JSON”

  • Red rice yeast Says:

    Red rice yeast…

    [...]S-Expressions: The Fat-Free Alternative to JSON | SHiNKiROU Blog[...]…

  • More On JSON Versus S-Expressions | Irreal Says:

    [...] a post on the SHiNKiROU Blog entitle S-Expressions: The Fat-Free Alternative to JSON is giving me second thoughts. The context of the post is a bit larger than log files and includes [...]

  • Warren Harris Says:

    I think you make a good argument for s-expressions over XML or JSON, but then fail to seal the deal at the very end of the article. Simply saying “Think of how Haskell tagged unions work” is probably going to lose 90% of your audience. Instead you should define and explain a schema for your person example, and then show how validation works. Is Scheme or Haskell required for validation, or are JavaScript tools available?

  • Aaron Says:

    I have never seen anyone support S-Expressions as a format in their online application. Are there any examples out there, in the wild?
    I’m intending to add S-Expressions to the API I’m working on for my company, but I may be hindered in doing this, depending on how Apigee or Mashery support content negotiation as proxies on top of our API.

  • Luis Says:

    S-expressions looks pretty, cool, but have minor nitpick with the xml-to-json example

    shouldn’t it be more like:

    {
    ‘name’: {‘first’:'John’, ‘last’:'Smith’},
    ‘age’: 25
    }

    possibly even:
    {‘person’:{
    ‘name’: {‘first’:'John’, ‘last’:'Smith’},
    ‘age’: 25
    }}

    Or maybe change the xml to something like:

    John
    John
    25

  • Blacktiger Says:

    Or, you could just use lists which are also part of json. [person [name John Smith] [age 25]]

    Even better… { ‘person’: { ‘name’: ['John', 'Smith'], ‘age’: 25 }

  • leah Says:

    They are basically awful and unreadable. JSON is light on the eye and very clear. Even XML looks better.

  • Ben Says:

    Why not just make your json less fat?

    {‘p’: ['Paragraph text here, ', {'b': ['bold text']}]}

  • Steven Turdick Says:

    XML is best for complex schemas.

  • Ferruccio Says:

    I’ve used s-expressions as the internal query language for a full-text retrieval system. The front end supports multiple human friendly query syntaxes which get compiled to s-expressions for direct execution by the back end. They are easy to generate, easy to parse (both by computers and humans) and very compact.

  • Aivar Says:

    Hmm, why didn’t you show document markup example in s-expression?

  • Sourav Chakraborty Says:

    JSON not only reduced size, it was also more readable and came with performance benefit. S expressions need to go a long way before it can be considered a viable alternative.

  • Mark Says:

    > However, JSON is not good at document markups

    That’s because JSON isn’t intended to do document markup. It’s a data marshalling notation. For that purpose, it’s very good at it’s job — lightweight, easy to parse and easy to read.

    If you want a markup language, use one. If you want a fast, cheap and portable way to exchange data between applications, JSON is the way to go.

  • Tim Says:

    Re. json for document markups, you might be interested in this experiment that uses normal js literals to describe templates, and is inspired by lisp templating approaches: https://github.com/twfarland/don

  • Matt Says:

    Simple (json) is better than complex (xml), complex is better than complicated (s-expressions). Stop complicating things, please.

Leave a Reply