4 ms·
If you love the expressiveness of S-expressions but hate the super noisy parenthesis, check the sugar version, called "sweet-expressions". http://readable.sourc
by jhrobert 14y ago
If you love the expressiveness of S-expressions but hate the super noisy parenthesis, check the sugar version, called "sweet-expressions". http://readable.sourceforge.net/ http://readable.sourceforge.net/
- martinced 14y agoYou have to love the intellectual dishonesty of that site you linked to: they quote Paul Graham whose not just a big Lisp dialects advocate but also probably partly responsible for the regain of interest in Lisp dialects... Yet they quote pg as if he ever said that Lisp source code were ugly. Regarding the "noisyness", I really think that the one and only place that you can really criticize is the closing of the outermost method. And any text editor worth its grain of salt can be programmed to automagically collapse these closing parentheses. Hence preserving the eyes of non-lispers. Also, when you're using something like paredit or subpar you hardly ever have any issue of non-matching parentheses. I'm really surprised that people are still whining about that instead of trying to focus on the bigger picture: the benefits that homoiconicity brings to the table.
- orthecreedence 14y agoAgreed. You don't hear people bitching about all the {}'s in C and Java, but when lisp comes up you'd think parens were responsible for the plague. Get a real editor and deal with it. Once you write your first macro, you'll realize how stupid all the whining was and why homoiconicity is in many aspects superior to other syntaxes without sacrificing much at all.
- chc 14y agoWell, a lot of it is that Lisp uses parens for everything while most other languages use a variety of syntactic tools. For example, declaring a bunch of variables in Lisp: (let ((a 1) (b 2) (c 3)) (format t "They are ~D, ~D and ~D~%" a b c)) The same thing in C int a = 1; int b = 2; int c = 3; printf("They are %d, %d and %d\n", a, b, c); Lisp used parens around the whole construct, as well as around the assignment list, around each individual assignment and to do the printing. C completely eschews some of these parens and uses = and ; to fill essentially the same role as the others. Only `printf()` keeps the parens. In short, C has lots of different syntactic symbols, while Lisp has relatively few. To illustrate further, Clojure gets the "OMG parens" complaint a lot less than most Lisps because it consciously shies away from the traditional parens-everywhere look of Lisp. For example, the above code in Clojure: (let [a 1 b 2 c 3] (printf "They are %d, %d and %d\n" a b c)) Still more parens than C, but the difference is marked — the assignment block is clearly set apart by syntax, and the assignments are paired by juxtaposition rather than by grouping into lists. Parens are used relatively sparingly. This isn't to say that this is really a problem, but the idea that parens in Lisp are equivalent to brackets in C isn't really right either. Parens in Lisp are used in place of nearly every bit of syntax in C, from braces to equals signs to semicolons.
- chc 14y agoI find that alternative syntaxes like this for S-expressions tend to get really awkward when confronted with real-world Lisp code. For example, the following code sample†: (define (pointless-function a z) (let* ((numbers (map (lambda (n) (* n 2)) (range a z))) (multiple-of-three? (lambda (n) (= 0 (mod n 3)))) (multiples-of-three (filter multiple-of-three? numbers))) (printf "Your numbers are: ~s~%" multiples-of-three))) AFAIK, this code only gets noisier when you introduce a paren-free syntax, as you need to introduce hacks to get around the simultaneous necessity and lack of parentheses. † OK, I'll grant you, this function is not at all realistic. But I think the structure of the code is pretty lifelike. I didn't have any Lisp code at hand to use as an example, so I just banged out something that used let and lambda to illustrate that the structure of S-expressions can be pretty intricate.
- qu4z-2 14y agoMy ideal s-expression syntax would allow you to replace some brackets with whitespace. For instance, your function would become: define (pointless-function a z) let* numbers (map (lambda (n) (* n 2)) (range a z)) multiple-of-three? (lambda (n) (= 0 (mod n 3))) multiples-of-three (filter multiple-of-three? numbers) printf "Your numbers are: ~s~%" multiples-of-three Obviously there are some down-sides, but the main idea is that the mapping should have no knowledge of the language details, and be a pure s-expression transform. I really should explore the idea more. I have no idea whether the above example can even be uniquely parsed.
- praptak 14y agoClojure managed to keep the Lisp expressiveness while keeping the parentheses nesting low. I don't think I can list every Clojure feature that aids this goal but here's a few: * bindings (let forms & similar) make implicit pairs, so it's (let [a 1 b 2] ...) instead of (let ((a 1) (b 2)) ...) * square brackets as shorthand for vectors - the nesting level might be the same, but the second kind of brackets somehow helps the brain find the way in the parenthesis jungle. * lots of helpful macros (e.g. -> and ->>) and other helpers that help write terse code with low nesting. #(+ 5 %) as shorthand for (fn [x] (+5 x))
- Jach 14y agoClojure's way has been generalized into a nice standard called edn (extensible data notation): https://github.com/edn-format/edn https://github.com/edn-format/edn I wish this was as commonplace as json and xml...