# Are square brackets and curly braces in Clojure still S-expressions?

I am trying to learn Lisp and looking at all the Lisps out there and their differences.

I see that in some implementations of Scheme, you can use square brackets interchangeably with round brackets for readability, so because they are treated the same, I assume they are still just S-expressions like everything else.

However, in Clojure I see that square brackets and curly braces are used to represent different data types like vectors and so on. Are these also still valid S-expressions, or must they be considered atoms? Doesn't this "break" the whole concept of S-expressions, thereby making Clojure an "impure" Lisp?

• Technically "if square brackets are s-expressions, how can you express them with parentheses instead?" was not part of the question, but that's what I want to know. Mar 14, 2020 at 0:55

## 2 Answers

Literal notation for vectors and maps (ie, square brackets and curly braces) are just read-time sugar, and anything you can represent with that notation can also be represented with S-expressions. As a result, there's no loss of power or homoiconicity, and indeed reader macros (which I understand are even more powerful) are available in a number of lisps.

Incidentally, note that Clojure now provides a mechanism for creating custom "tagged" literals, which, like other literals, are transformed to S-expressions before they are compiled and interpreted.

• Mmm, your answer makes me think that I understand less than I thought I understood about Lisp. So what you are saying (I think) is that the square and curly brackets are in fact not S-expressions themselves. I thought the whole idea with Lisp input is that everything is an S-expression. Looks like I need to do some more digging before coming back to read your answer again. Thanks! Apr 18, 2013 at 6:00
• That's correct - they aren't S-expressions. Lisp syntax starts with S-expressions, in that everything that can be expressed in the language can be expressed with S-expressions. But Lisp syntax doesn't end there: many Lisp compilers have an explicit read-macro phase, in which special patterns in the source code are transformed into S-expressions. This lets language authors offer programmers human-friendly syntax. The important thing to note is that because anything represented with these special literals can also be represented in S-expressions, none of the benefits of homoiconicity are lost. Apr 18, 2013 at 13:33

S-expressions are a textual representation for data. Numbers, symbols, cons cells, lists, strings, ... Common Lisp also has textual representations for arrays, vectors, more number types, characters, ... Common Lisp also provides a user-extensible reader, so that the user can add more textual representations for data types. Sometimes this mechanism is also used to alter the syntax of the Lisp programming language (for example to support infix expressions or statements from other programming languages).

Thus, if a Lisp dialect offers textual representations for additional data-types, this fits well to the idea of s-expressions.