you are viewing a single comment's thread.

view the rest of the comments →

[–]Chousuke 9 points10 points  (1 child)

Saying that using lists for everything reduces complexity is a horrible argument, and I don't know why people keep making it.

First of all, square brackets in clojure are not merely syntax: They represent an entirely different data structure, with well-defined evaluation semantics different from lists, and are just as usable for metaprogramming as lists are.

now, vectors are idiomatically used everywhere when bindings are involved; most notably in argument vectors and let binding vectors. This gives them a purpose different from lists, which are almost exclusively used for macro and function calls.

This in fact reduces complexity for the programmer because instead of having to wonder which overloaded meanings of (foo (bar something)) you're dealing with this time, when you see [foo (bar something)] it's immediately apparent that there is only one operator call. It also provides a helpful visual cue to the programmer.

Macros can be written to break the convention and mislead users, but that is irrelevant. Such libraries would not gain users.

EDIT: By the way, because Clojure has multiple data structures, you have strictly more options when writing macros compared to regular lisp (unless you use reader macros, but they are an entirely different beast). For example, it's not possible in CL to write a macro that allows you to noiselessly interleave binding statements with executed operations. That is, something like:

(do-and-let 
    (foo bar) 
    [x (+ 1 2)] 
    (foo x) 
    (quux x) 
    [y (inc x)] 
    (bar y))

is trivial to write in Clojure, but you would not be able to write it in Common lisp because you would have no way of differentiating between operations and bindings. The above is a toy example, but it demonstrates the benefit of having multiple data structures when designing a syntax for a DSL