34 comments

[ 2.8 ms ] story [ 52.8 ms ] thread
By the guy behind the thing/geom library:

https://github.com/thi-ng/geom/

Check out the examples, it's very pretty. The little I've played with it it's been incredibly ergonomic and fun, in the hiccup-style you see in Clojure. Haven't come across anything like it in other languages

The geom library is amazing! Client-side and server-side generation of charts with same code. The documentation is also great.

The project was written in a Literate Programming style. These turned out to be an obstacle for contributions, so there is an ongoing effort to migrate the code out of that. You can find the latest version on this branch: https://github.com/thi-ng/geom/tree/feature/no-org

> Even after a short while, you'll find these brackets seem to become automatic and mentally disappear

Is this really true? It's by far the most off-putting thing about Lisp dialects to me. Trying to get nested parentheses to match is extremely tedious when I have to do it in non-Lisp languages. It seems horrific if my whole programming experience is one long exercise in "why doesn't this bracket match!?!?!!". I know it can't be this bad because too many people have no problem with it, but it's the only thing I can think when I see some Lisp source code with 50 nested parentheses ...

Most editors have a plugin for "paredit" mode that auto-balances the parens for you.

(And code with 50 nested levels of parens is Bad Code, just like too much nesting in a C-like language)

Parinfer is also really nice. It rearranges your parens automatically based off of your indentation. I still prefer something like Paredit, or Smartparens for the power user features, but Parinfer is really intuitive and just works without having to learn new editing commands or hotkeys. It's my go-to recommendation now for people coming to lisp for the first time because it makes working with lisp code very similar to working with an indentation-based syntax like Python.

https://shaunlebron.github.io/parinfer/

You don't even have to think about parenthesis matching when your editor does it for you.

When using Emacs, the editor can ensure the parenthesis always match. It can also show you which parenthesis match, and if you insist on allowing having non-matching parenthesis, it can show you exactly where they don't match. So even in that case you don't have to worry about it because the editor will point it out to you.

Parenthesis are probably the most trivial and unimportant thing about Lisp, and people get way too hung up about them.

What's far more important is the power that Lisp gives you, how easy it is to program what you want in it, and how elegant and easy to understand the solutions you come up with are.

Instead of having some kind of spaghetti code monstrosity full of ridiculous boilerplate as you would in other languages, you could have a nice and simple solution in Lisp. Isn't that worth allowing some extra parenthesis in to your code?

It's really no different. Consider this function in Go:

  func Foo(s string) string {
    println("hello")
  }
And in Clojure:

  (defn foo [s]
    (println s))
The Go code has two () pairs and one {} pair. The Clojure has two () pairs and one [] pair. There aren't more overall parenthesis, they are just in a different place. Any decent editor will catch missing parens just as they would missing braces in other languages.

There are some cases where you do get a few more parens, e.g. with mathematical operators, but overall it's not that different, it's almost completely user perception.

Honestly, I wish Clojure had more parenthesis. As a Lisp fan, square brakets make me grrr.

I don't want to have to think about which delimiter I need where. Knowing that it's always going to be a parenthesis makes my life so much easier.

That's true for writing code, but I think the man benefit is when you're reading it. Parenthesis tell me that there is a function application occurring, and square brackets tell be that bindings are being initialized. Then parenthesis, square brackets, and curly braces help me easily find lists, vectors, maps, and sets just from a quick visual scan of the code. Clojure also does a nice job of eliminating unnecessary parens, such as the ones surrounding pairs in a let binding. So instead of this:

  (let ((x 1)
        (y 2))
    (+ x y))
In Clojure, it becomes:

  (let [x 1
        y 2]
    (+ x y))
I don't think I've ever been confused as to which were the bindings in a let block. It's obvious from the indentation and the parenthesis.

Granted, it's a bit easier to pick them out with square brackets, but for my taste I'd rather just have homegenous delimiters everywhere.

> Then parenthesis, square brackets, and curly braces help me easily find lists, vectors, maps, and sets just from a quick visual scan of the code.

How often do you want to do that? Wouldn't you be more interested in what the variable is called or who it's passed to?

> Is this really true?

Yes. There comes a moment in which you suddenly stop minding parentheses. For me it was when I started reading SICP and doing its exercises on paper. After writing a couple Lisp expressions by hand, something clicked in my brain, and since then I don't need to count parentheses anymore.

I strongly suspect following the Lisp style of indentation and placing parens (closing parens go together, instead of one per line like in Algol-derived languages) is vital to achieving that.

This was my experience too. I also found The Little Schemer, ANSI Common Lisp and Practical Common Lisp useful books. Also using Emacs for a while helps since you have to work with Lisp eventually, especially if something goes wrong (and there's a lot of packages that'll take contributions if you end up using and fixing those too).
I think it's just an exposure thing, it takes time to adjust to if you're not used to it, but after a certain amount of time the parens fade into background noise. The hardest part is having to learn a tool like Paredit to intelligently restructure lisp code, but tools like Parinfer are making that transition easier.

After working with mostly Python and Clojure since 2015, I now have a similar gut reaction to curly brace languages that most people have to lisps. I find ClojureScript much more readable and aesthetically pleasing than Javascript.

After a while the parens became something I enjoy having. I like being able to structurally edit code, and comment out paren expressions by prepending them with '#_', I feel like I can edit Clojure code much faster than JavaScript code.
I have the same feeling. After spending a couple years writing Lisp code (CL and Clojure), the "normal" Algol-like syntax now feels unwieldy.
> I strongly suspect following the Lisp style of indentation and placing parens

Definitely - I have started writing JavaScript braces for nested callbacks in that style as well because it makes much more sense.

Yes, it's true. Only takes a few days. I understand why people are disturbed when they first see a Lisp; but really, truly, honestly: It's a total non issue. I never think about it and I use Clojure every day. It's the same as getting used to any other language syntax.
thanks! good to hear :-) I will definitely have to take the deep dive one day into one of these modern Lisp variants.
You don’t see them in the same sense you don’t see multiple closing braces in java or c.

The style in lisp is to keep all the closing paren on the same line: ))))

But in java or C you’ll sometimes see a function that ends like: } } } }

(Hmm my newlines didn’t cone thru on those braces)

Not exactly apples to apples comparison, but it illustrates how you can start to unsee those parens.

In a decades old java code base where so many has touched the code. It can look like this:

                            }

                        }

                    }

                }

            }

        }
    }
}
Believe it or not, it's easier in lisps, because the uniform syntax enables more aggressive tooling. I have more trouble with paren-matching in, say, js, than I do in clojure.
Install a rainbow brackets plugin for your editor if available. That mostly solved the paren matching Problem for me in all languages
I’ve used Lisp for decades, so it’s hard to remember a time when the parentheses bothered me, but every new programming language has some surface syntax that can be off-putting. I used to hate the hard to type curly braces when I started with C, my fingers didn’t know where they were on the keyboard; at the time, I was programming with languages that used BEGIN and END. Now I prefer curly braces or even indented languages like Haskell or Python.

I encourage others to learn lisp. It’s really not a hard language, and the parentheses don’t get in the way after a brief period of acclimation. It also opens up the real power of Emacs customization and programming, which is done in Lisp.

Emacs-lisp is a great introduction to lisp syntax. Because Emacs is a bunch of UI code, it's very imperative in nature. You can learn lisp without having to also dive into a lot of functional programming concepts at the same time.
I just want to say, what has kept me away from LISP has nothing to do with parentheses. There are two "facts" that I can share to represent why I dislike LISP.

The first is a quote bathed in absurdity from an actual LISP manual:

> setf can also be used with any of these functions to change an existing component of x, but setf will not make new components. So, for example, the car of a cons can be assigned with setf of car, but the car of nil cannot be assigned with setf of car. Similarly, the car of the car of a cons whose car is a cons can be assigned with setf of caar, but neither nilnor a cons whose car is nil can be assigned with setf of caar.

I think this sums up the aesthetic horror that LISP is to me. Pretty sure it was written by Dr. Seuss.

But a far more important factor exists: There are no decent paying jobs for LISP programmers outside of the browser which is a personal hell to me. Besides Clojure, I know of no real foothold in the professional world. I have no doubt there are outliers, but, that's just not the kind of thing to bet on.

So no, not bothered by the parentheses. Bothered by lack of real words with real meaning and lack of motivation to tolerate the ugliness.

So a flawed paragraph in a manual written by who-knows-who is enough to put you off from an entire programming language?
No, that is just one example. The point is the stewards of this class of languages have, over the decades, never thought it wise to humanize the language despite no technological problem in doing so.

There is no need to set a high bar to filter a language from my attention. There are thousands of them.

Anyway, the point is that there are reasons to dislike LISP besides the parentheses. It's all subjective in the end.

> actual LISP manual

It's not from a LISP manual, it's from the language specification of ANSI Common Lisp.

You'll probably find non-obvious wordings in many programming language specifications. Don't learn a language from a spec and don't try to understand everything in a language spec, if you don't know the language.

I've used a lisp (Arc) for weeks and the parens are still mildly annoying but I can live with it.
> I encourage others to learn lisp. It’s really not a hard language, and the parentheses don’t get in the way after a brief period of acclimation.

Every time I try this, like twice a year, I get annoyed while setting up a development environment that supports the particular Lisp (usually Clojure), its syntax and the REPL. Last time I tried it was Spacemacs that didn't work as announced, on both Linux and macOS.

I am a Vi user and I would prefer to use that instead of learning a new environment such as Emacs. I want to set this up and have it work as frictionless as possible because learning a new programming language and its ecosystem is already enough work. However the Vim plugins (e.g. fireplace) also didn't "just work".

TXR Lisp comes with an accurate syntax definition file for Vim (and only Vim). Well, not exactly "comes with": txr.vim is in the root directory of the source tree. Some distros seem to package that, like Arch.

The whole project was developed using Vim.

Vim supports normal Common Lisp out-of-the-box. Just save your file under a .cl or .lisp suffix.

In 18 years of working with Lisp in Vim, I never had a problem. Never installed a plugin or did anything special (other than developing that syntax file for TXR Lisp). At most I played with the content of :lispwords; that's about it.

While I truly appreciate emacs and vim, I had the same problem. Ultimately I went with IntelliJ IDEA and a plug-in for Clojure called Cursive. It's served me well; getting past the environment challenges and into the language itself was a godsend.
Doing any Swing UI apps in Clojure is a breeze, and its very interactive during development, I rarely need to write any java code for any of my personal apps, also JEdit is a good fit as an editor/ide for Clojure , using Jedit Macros gives it a Java...ish emacs feel. if only there was debugger.