Snark aside, what does this buy us that these existing markup languages don't?
I appreciate all that Rich Hickey does for programmers, but aside from his name, this just adds to the noise that already exists in this domain.
Snark aside, what does this buy us that these existing markup languages don't?
I appreciate all that Rich Hickey does for programmers, but aside from his name, this just adds to the noise that already exists in this domain.
What does it buy "us"? Well, it doesn't buy "us" anything. They needed a data interchange format and I assume it made more sense to use Clojure's primitives than parsing up JSON. Why would a project written using a homoiconic language use anything but that language to exchange data between its components?
edit: Said best by this tweet by fogus:
"Clojure devs have been using #Clojure data as an interchange format all along. ..."
There are quite a few people here interested in clojure and Rich Hickey's work.
Even in JavaScript it's better to parse JSON instead of eval'ing, because you don't want to execute stuff that would "happen" to be contained in the data interchange format.
Using Read in a lisp is typically safe, so long as you turn off reader macros and the like.
They are separate:
* http://docs.python.org/library/ast.html#ast.parse
* http://docs.python.org/library/ast.html#ast.literal_evalI also think that while Boolean expressions in Lisp are less natural than "this AND that OR another", they are clearer when they get large (with good formatting of course).
1 + 2 * 3
one plus two times three
But in Lisp when read naïvely left-to-right this becomes "times add one two three", which is nonsense in English. (* (+ 1 2) 3)
times add one two three
Most people cite "lots of brackets" as their reason for disliking s-expressions, but I think the unfamiliar ordering is a less superficial criticism. Of course, for those of us manipulating ASTs they're very natural, because we see language as trees.So, "the product of the sum of 1 and 2, and 3"? Reads fine in English, as long as you refer to the results instead of describing what to do. :)
(function1 (function2 1 2 3))
function1(function2(1, 2, 3))
There is no difference in the way we read the first over the second."Multiply the sum of 1 and 2 with 3".
Of course 1 + 2 * 3 is more familiar that way, vs the Lisp way. But you have the Lisp way wrong (unless your example was Smalltalk)... it would be:
(+ 1 (* 2 3))
Which could be read left-to-right as "sum 1 and the product of 2 and 3".Also, most math functions in Lisp are variadic. So if you have this in infix:
x + y + z + 1
// x plus y plus z plus one
You could do it in Lisp as: (+ x y z 1)
;; sum x y z and one
There are plenty of cases where an algorithm is naturally expressed as a map or a reduce, where infix or prefix has nothing to do with it. I don't find myself using a lot of the kind of math that would be better in infix.It might even be useful to give math operators new names in Lisp, because of the way that things like < > = == are a bit awkward when read as their equivalents in infix. They are all variadic, after all.
Compare:
(x == 10 && y == 10) && (x < y && y < z && z < 100)
Vs. (and (== x y 10) (< x y z 100))
That's already an improvement, but the reading is strange. So what if we alias those operators? (all-true? (same? x y 10) (ascending? x y z 100))
I don't know if I'd actually use those names, and I don't think I would do this in code, but you get the point. You can even tell how a list of numbers is sorted in Lisp by simply doing: (apply < nums)More and more I hear people 'they've been doing this in lisp all along' so I make a naive guess that in the future lisp genes will reappear in more favorable settings and won't get dismissed as they were before. It's already happening as for gc's and closure right ?
Erasing that initial bad impression may be a generational thing. Even heroin goes through cycles where a new generation comes along that hasn't seen anyone die of heroin, they make heroin cool for a while, and then the horrifying results inoculate the culture against the idea that heroin is cool for another fifteen or twenty years. Lisp will get another chance, and it can afford to wait.
Also, I think next time around it won't be Lisp, the universal solution. It will be a Lisp. It might not even be called Lisp. It might be called "Clojure" or something odd like that ;-)
JSON is a lowest common denominator. The features that you just specified are not directly available in JavaScript. Therefore data represented in this new format will be very, very clunky to access from JavaScript.
Besides, without highlighting Javascript's limitations, how will we ever get it to improve?
In general when you're trying to achieve interoperability, any features and distinctions supported in your data format that are available in one language and not in another will be causes of interoperability problems.
For instance with JSON, the format allows you to differentiate between values that are numbers and values that are strings. Languages like PHP, Perl and JavaScript do not particularly care about that distinction, and therefore coding values consistently is hard in those languages. (You can guess, but sometimes guess wrong - your zip codes are usually represented as numbers and sometimes strings.) Languages like Ruby and Python do care about the distinction, and so applications can have difficulty accepting JSON from the previous languages.
This new format allows more places for this kind of issue to exist. We have distinction between different types of integers. We have symbols (2 kinds if you have them). We have sets. We have 2 different kinds of lists. And we have a plethora of possible extensions, every one of which can behave differently in different implementations.
When both sides speak Clojure, this is going to be a very convenient choice. When they don't, every one of these obvious features is going to be a source of headaches down the road.
That is why data exchange formats should be in a least common denominator between the languages in question.
Having those as distinct different types in a data exchange-format seems awfully (lisp/functional-language) implementation specific. IMO conversion from "generic list" to "whatever type of list makes sense in your domain" should really be done outside of an data-interchange format. A data-exchange format should not need to meddle with any list besides "generic list".
I do think sets (as opposed to lists) brings valuable semantics, though I can see how that is up for debate.
Otherwise, you bring up fair points, but I don't mind a format with ambition. Merely presenting a new JSON would not be very exciting.
However, edn is not without legacy. Part of that legacy is Lisp and s-expressions, and deserves some respect and accommodation. If that means readers map the [] and () to the same code path, well, that's not much work. Writers can always write only [] if they prefer.
Having the distinction has proven tremendously useful to Clojure, and might to other applications as well. In particular, consider DSLs written in edn, which, like Clojure, might need to distinguish calls or grouping from list/vector data. For all the bitching that goes on about parens, few people would want to work in a language without them :)
I guess you're not a fan of Forth?
JavaScript has hashmaps with non-string keys, they're just not exposed by JSON. Also a set can be treated as an array in a non-clunky manner. Likewise for treating an integer as a Number.
I'm not sure the design goal of edn is to actually be consumed from JavaScript though?
Other than that, the major difference seems to be that EDN does not have a root-element or requirement for such, and as mentioned in the introduction can be used for streaming and real-time content etc.