Hacker News new | ask | show | jobs
by 616c 4117 days ago
I like the side-note.

> As a side note, expressing configurations in Clojure S-expressions makes a ton of sense. Clojure S-expressions provide a superset of JSON and Clojure's eval allows you to define a function to compute certain values. It's an escape hatch so that you're configuration files don't need to become accidentally Turing complete. The Turing complete nature of your configuration files is well defined as Clojure.

I had posted a while back wondering why more formats do not just derive from sexp or SXML (yes, say that out loud in the office). As I think some Lispers (I am even below beginner) cannot help but notice that if sexpr are coincidentally (I am sure it can be done without, but still, I am not sure if McCarthy and company just started with sexp or choose it specifically and held their ground beyond it was their choice) core to the lisp's homoiconic power-features, why more people do not just want sexp as the core data definiton, keep the data and program as close as possible, and just macro the data back, tossing back and forth between code and data as the division is limited.

Anyway, I like that far more intelligent people than me not only like this idea, but are encouraging it and pushing it forward.

(Yes, flame away. I know some people love Lisp and hate, I just thought it is an interesting premise; I am ready for you to throw shoes at me, HN.)

3 comments

Steve Yegge wrote a blog post about this a few years back that I found eye-opening.

The whole nasty "configuration" problem becomes incredibly more convenient in the Lisp world. No more stanza files, apache-config, .properties files, XML configuration files, Makefiles — all those lame, crappy, half-language creatures that you wish were executable, or at least loaded directly into your program without specialized processing. I know, I know — everyone raves about the power of separating your code and your data. That's because they're using languages that simply can't do a good job of representing data as code. But it's what you really want, or all the creepy half-languages wouldn't all evolve towards being Turing-complete, would they? https://sites.google.com/site/steveyegge2/the-emacs-problem

Great quote. This idea is still not too popular, unfortunately. There are a lot of folks out there that get real mad when configuration is code. Notably, sysadmins that feel forced to learn Clojure or <insert-language-here> to configure an application. "Why not XML or JSON?", they say.
Most well-designed applications will separate the administrative interface (configuration) from a programming interface (the API), even if the same langauge is used for each one. If you do this properly, most administrators are not going to care what language your configuration is in so long as it's clear and consistent.

In my experience, the main annoyance using programming languages for configuration is the need to use explicit string literals for every string in your file. List separators are another major source of clutter in configuration files, though this is theoretically not a problem in clojure. The second problem is the tendency to be undisciplined and allow too much program logic in configuration files resulting in complex and unclear relationships between options and behavior.

Personally I do all my configuration in yaml now. Even if I was using lisp I would use yaml whenever possible for configuration and static resource definitions, because yaml is very portable.

It really depends on the environment and culture. In Python web apps for example it's very popular to keep project configuration in Python dicts and lists, which are just Python code (as opposed to using something like YAML or JSON for config).
Popular, but an anti-pattern. People start including production configuration as a module inside the build.

The Right Way (TM) is loading from env vars.

By "inside the build" do you mean in the git repo?

Because there isn't really a such thing as a "build" for a Python web app, it's a dynamic language. It's not like Java where you'd have to recompile the whole app if you packaged your config inside the compiled jar.

In Django apps, there's an env var called DJANGO_SETTINGS_MODULE that points to one of multiple settings.py files, and you change that var depending on which environment you're working in. Then typically you also would want to store individual variables that need to be secure (stuff like any secret keys and database credentials) in env vars, but the overall structure of your config is just a python dict in settings.py.

For reasons that Yegge touches on in the blog post I linked above, you really want a tree structure for configuration of any complexity, and env vars don't provide that.

I think he means that the configuration file is on the library path is read using an import statement rather than parsed explicitly from a standard path like etc/.
Well, technically, JSON is just a Plain Old Javascript Object, with restrictions (no expressions, quoted keys).
Sort of, at least in the sense that you can eval JSON from JS code rather than having to parse it yourself. This is one of many language concepts that JavaScript cribbed from the Lisp/Scheme family of functional languages.
Once you use Clojure's EDN, you start to cringe when you see JSON.

Spec - https://github.com/edn-format/edn

Walkthrough - http://www.compoundtheory.com/clojure-edn-walkthrough/

I was excited to hear someone's Guile Scheme answere to Sinatra, Artanis (yes, I know, cute), led me to the Summer of Lisp winner list, including this of course and the Learn You a Datalog guy. Naturally, that led me to EDN.

Thanks for reminding my to finished the EDN docs.

http://www.learndatalogtoday.org/

Tell me about it. First thing I asked when I saw HTML over a decade ago was "Oh so you can close tags out of order?" - "Uhm, no, the last opened tag must be closed first" - "Then why do I need to say its name when closing? There's no ambiguity, it's always 'close the last opened tag', so why say its name again?". Folks at W3C must not know Lisp.
I'm happy to disclaim that I have nothing to do with the mess that is the HTML standard! But if I had to guess I would say that the ending tags in HTML add a modicum of redundancy that allows for some of the crazy/creepy/smart error correction browsers have been doing for decades:

You can close your P tags or not; if you don't, the next opeining one is a new paragraph, with the previous one assumed closed. Similarly with LI tags in lists or the multiple levels of stuff in TABLE.

That makes HTML "code" marginally easier (at least in terms of effort) for humans to write and maybe also read, and for programs to error-check and correct. It's also led to waves of shitty HTML code and generations of smarter programs to guess the intentions of stupid HTML generators.

XML, being more strictly defined, could have followed the lead of Lisp and done without the closing tags. I guess people felt the need for a security blanket of closing-checkable tags, or its slightly better human-readability.

> That makes HTML "code" marginally easier [...] and for programs to error-check and correct.

This is a great point. It's not subjective and I'm pretty sure it's right. I hadn't thought of that. I guess there is a use for redundancy sometimes. If the point is to make the language welcoming to beginners then this decision makes sense.

I wonder, though, if they made the same mistake that the SQL people did, in devising a language with characteristics that are advantageous to some imagined target group ("non-programmers") but that ends up getting used just by programmers who then hate the training wheels.

> "Then why do I need to say its name when closing? There's no ambiguity, it's always 'close the last opened tag', so why say its name again?". Folks at W3C must not know Lisp.

HTML (well, SGML, in this case) was designed for humans hand-authoring large documents. If your opening tag is a few hundreds lines above the closing tag, a little redundancy is handy.

Remember, HTML is a markup format, not a data format. Tags were designed to add a bit of data to what is otherwise a plaintext document intended for human consumption.

We already have a solution for that:

  if whatever
    ...
  end # whatever


  (p
    ...(bunch of stuff inside p)...
  ) ; p
Now it's optional, not part of the standard, and the language is cleaner for it, while allowing for a way to help your described scenario.

Folks at W3C want to fix all kinds of non-existing problems (like HTML5 canvas when there's already OpenGL viewports).