Live data from Hacker News

S-expressions

igor.io

31–40 of 46 posts

Re: S-expressions

#32
post #27
post #19

Earlier quoted context omitted.

It is if you want to differentiate between a list of lists and a map. Maps are not natively supported in s-expressions. So there is a need to create a sub-language to handle special data structures. I have done this as well. But I use a special namespace '#dict' for example. So it would be (#dict (k1 v1) (k2 v2)) This way there is less of a chance of collision between data and this sub-language. It also allows for ex…

That's an nice idea, using # as a straight-up constructor. I've always found hash-tables to be a colossal pain to create in Common Lisp. I tried to create a special JSON-esque syntax in CL for them, but it wasn't a smooth semantic drop-in.

Yeah I think it is pretty neat too. I had a couple of design ideas. This way I can persist some other structures (from Python for ex):

For set():

   (#set v1 v2 ...)

 
For circular object graphs, I can encode an object reference to avoid serializing the same object twice:

   (#ref oid)
Then of course there are custom class names I can pass in to serializer and deserializer:

    (#MyClass (attr1 val1) (attr2 val2) ...)

This might not map to all languages but it worked for me.

Re: S-expressions

#33
post #23

You could write code in XML and JSON too, you just need to define meanings. [add][item]1[/item][item]2[/item][/add]

> You could write code in XML and JSON too

And many do (e.g. Ant), but doesn't that sadly look like reinventing the wheel?

Re: S-expressions

#34

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/

I 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.

Re: S-expressions

#35

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/

Clojure 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))

Re: S-expressions

#36
post #35

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/

Clojure 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…

Clojure's way has been generalized into a nice standard called edn (extensible data notation): https://github.com/edn-format/edn I wish this was as commonplace as json and xml...

Re: S-expressions

#37

Why are the keywords written with a quote? > (keywords '(useless microframework academic swag)) Shouldn't it be a list with strings or something? What if the keywords were complex structures not just strings?

The only Lisp I know is Racket (basically Scheme), so take the following with a grain of salt. '(foo bar baz) is almost the same thing as (list foo bar baz). However, ' also makes the contents of the list into symbols, not variable references. Basically, '(foo bar baz) returns (list 'foo 'bar 'baz), not a list containing the values of the variables foo, bar, and baz. Symbols aren't much like strings. They're immutabl…

> Symbols aren't much like strings. They're immutable, and actually just refer to a unique number, not characters.

Depending on language, that could make them exactly like strings. :)

Re: S-expressions

#38

A highly recommended read from defmacro. http://www.defmacro.org/ramblings/lisp.html Other articles on the site are very nice as well: http://www.defmacro.org/

Yes, it is a great article, but it saddens me that we have to invoke XML to explain S-expressions rather than the other way around. S-expressions have been around since 1958! They are maybe the best reason that everyone should learn Lisp even if they don't wind up using it much, just so they know there are problems it already solved long ago, and they don't need to reinvent the wheel.

Re: S-expressions

#39

Earlier quoted context omitted.

The only Lisp I know is Racket (basically Scheme), so take the following with a grain of salt. '(foo bar baz) is almost the same thing as (list foo bar baz). However, ' also makes the contents of the list into symbols, not variable references. Basically, '(foo bar baz) returns (list 'foo 'bar 'baz), not a list containing the values of the variables foo, bar, and baz. Symbols aren't much like strings. They're immutabl…

> Symbols aren't much like strings. They're immutable, and actually just refer to a unique number, not characters. Depending on language, that could make them exactly like strings. :)

If you have immutable strings and a smart compiler, yes, you could indeed have strings and symbols that are functionally identical. In fact, in Old Lisp, there were no strings and symbols were used for everything we use strings for now; that lead to weak string handling and it's why Common Lisp and all modern Lisp variants have a string type.

Re: S-expressions

#40

Why are the keywords written with a quote? > (keywords '(useless microframework academic swag)) Shouldn't it be a list with strings or something? What if the keywords were complex structures not just strings?

You're asking two questions here. First, about the quote. I'd say it's a mistake. The author hasn't been completely clear (and I think is possibly a little confused) over the difference between s-expressions in general, which are simply a tree-structured representation, and Lisp code, which is written as s-expressions but is subject to additional rules.

In this case, it's pretty clear from the surrounding discussion that these s-expressions are not intended to be executable code. That being the case, there's no reason to use the quote. This line should have been

> (keywords (list useless microframework academic swag))

Secondly, as others have mentioned, there is an important difference between symbols and strings that is not necessarily easy to explain -- indeed, it took the Lisp community a few decades to get clear on it. Fundamentally: strings are data; symbols are names. Notice, in this example, that all of the keys in the dict, as well as "dict" itself, are represented by symbols. That is because each of these names something in the domain of the program that manipulates the representation: an object type, an attribute of an object type, or, in the case you are asking about, a member of a set of keywords.

If you've used enumeration types in a language that has them (C/C++, Java, C#, etc.), there's an analogy: symbols are like literals of a single, pre-existing enumeration type containing all possible names.

Post reply on HN