Lisp languages - what do you like about them?

Continuing the discussion from LFE Blog Posts, specifically:

I think the closest I have come to using a Lisp is through the influence it has had on Ruby - so I am curious, for those of you who love Lisp languages - what is it that you like so much about them? :003:

2 Likes

Lisp languages - what do you like about them

The parentheses.

Even though I wish parentheses weren’t optional in Ruby and Elixir functions, I do sometimes skip them, especially when I’m inside IRB or IEx.

In Lisp, every single parenthesis makes sense.

4 Likes

Ah so it’s mainly syntax?

Actually you’ve given me an idea for another thread! :003:

2 Likes

The syntax that’s so simple & powerful.
The macro system. The ability to dynamically compile code mainly based on macros to native code and keep solid computing performances.
The debugging is also so cool.

Sébastien.

4 Likes

Thanks for chiming in Sébastien :023: I think we need some code examples :003:

Do you (or anyone) have any snippets that you could share that highlights this? :blush:

2 Likes

Ok this is an illustration,
I wrote a closed source application 15 years ago that is used to tag unstructured documents. To express some conditions on tags, we define a simple language that can be used by the end user to express theses conditions.

simple extract of some possible expressions:

(defmacro all-inner (&rest tags)
   `(every #'(lambda(tag) (when-bind (io-count (gethash tag io-tags))
            (> io-count 0)))
      ',tags))

(defmacro some-inner (&rest tags)
   `(some #'(lambda(tag) (when-bind (io-count (gethash tag io-tags))
            (> io-count 0)))
      ',tags))

(defmacro none-inner (&rest tags)
   `(notany #'(lambda(tag) (when-bind (io-count (gethash tag io-tags))
            (> io-count 0)))
      ',tags))

(defmacro multi>= (count &rest tags)
   `(some #'(lambda(tag) (when-bind (io-count (gethash tag io-tags))
            (and (> io-count 0) (>= io-count ,count))))
      ',tags))

(defmacro multi<= (count &rest tags)
   `(some #'(lambda(tag) (when-bind (io-count (gethash tag io-tags))
            (and (> io-count 0) (<= io-count ,count))))
      ',tags))

(defmacro multi= (count &rest tags)
   `(some #'(lambda(tag) (when-bind (io-count (gethash tag io-tags))
            (and (> io-count 0) (= io-count ,count))))
      ',tags))

(defmacro all-outer (&rest tags)
   `(every #'(lambda(tag) (when-bind (io-count (gethash tag io-tags))
            (< io-count 0)))
      ',tags))

(defmacro some-outer (&rest tags)
   `(some #'(lambda(tag) (when-bind (io-count (gethash tag io-tags))
            (< io-count 0)))
      ',tags))

(defmacro none-outer (&rest tags)
   `(notany #'(lambda(tag) (when-bind (io-count (gethash tag io-tags))
            (< io-count 0)))
      ',tags))

then the conditions entered by the user are compiled to native code with the following:

(defmethod get-finalized-edit-cond ((scope-cond scope-cond))
   (let ((*package* (find-package :myapp)))
      ;; compile scope cond
      (setf (cond-fn scope-cond)
         (compile nil
            `(lambda (io-tags)
               ,(read-from-string (cond-string scope-cond)))))
      ;; call function to catch potential errors
      (funcall (cond-fn scope-cond) (make-hash-table :size 1))
      scope-cond))

this returns native compiled code that can be run against the whole document to check that the conditions are met or not.

The code of course is missing some parts, but that is the idea.
Cheers,
Sébastien

6 Likes

Because I’m not an expert in any of the Lisp dialects. I dabbled a bit with Clojure in the past and just touched LFE yesterday. I wished many times to learn Common Lisp or Schem, particularly Racket, but didn’t find any time for it.

3 Likes

Lisp was my first contact with Functional Programming so maybe I’m a little biased.
I fell in love with SICP as it opened my mind for so many new concepts.

I like the (lack of) syntax. Everything is consistent because the syntax is so simple… you can learn programming in just a few minutes if you have Lisp and a good teacher.
The fact that you can redefine some “core” functions like using the + symbol is enough for me to show that I’m really in control when I’m using Lisp, although I know that not every Lisp let you do that.
It fells like most languages get in the way sooner or later, but Lisp normally will not restrain your creativity since you can manipulate the structure and syntax as much as you want with the “code is data” concept.

Then we have the REPL. The Common Lisp REPL and the CL Condition System is just incredible, you don’t have anything like that available for any other language afaik. And you have some nice tools such as Slime that really makes you not want to code in any other language if you allow yourself to be too much spoiled for it.

I had not much time to play with LFE as of yet, but still I feel exactly like in the quote, if I can have Lisp and OTP in the same place, that’s for me!

8 Likes

It’s definitely the lack of syntax, and yes it really is a lack of syntax. The parenthesis is just the tree of the AST in text form, and because you have that you can treat it as data and operate on it with ease. What this means is that you can create any syntax you want. Lisp isn’t so much a language to make programs, but rather it’s a language to make languages to make programs, which is both a huge boon and a con.

Here though, this is a good read on as to ‘why’ lisp languages are awesome though:
https://www.defmacro.org/ramblings/lisp.html

5 Likes

I like how they got inspired by elixirs macro system and made it even more powerful, also I like that they can describe an editor’s configuration or a full system state (GuixSD)

3 Likes

So lisp was my first real contact with functional languages so it stuck. And I really do love its very simple and consistent syntax. You literally have literal terms where lists interpreted as things to do. And they are interpreted in the same way, the first element is what to do and the rest are arguments. Simple and consistent.

And lisps are a quite nice set of functional languages as well, especially LFE :wink: :smile:

4 Likes

My first functional programming language was Scheme and I was a student back then and had loads of time to think about thinking.

What I loved about Scheme, Clojure after it, and Hylang too (the three Lisps I had encountered) is how easy they are to learn, and explain the (lack of) syntax thereof. Even equipped with a pen and pencil you can do a lot of lisp than you can a non-lisp language.

Another thing I love about LISPs is the bare AST opens door to new kind of editing – structural editing.

Now on the flip side, I find Lisp code to be harder to read than it is to write. Maybe I didn’t have enough exposure to S-expressions to have prefix notation well etched, but I have to squint harder to comprehend my own S-expressions when encountered after a long time compared to, say MLs or C-s.

I was fortunate to work with Lisp at work (ClojureScript, 2014) briefly, I must say it was a pleasurable experience I wouldn’t mind repeating.

3 Likes

Yes, my first contact with lisp was at school. I was doing a CS engineering class at that time. The professor taught us Lisp with a chalk on a blackboard !!!
We also had paper exams where we wrote lisp programs…
I loved it (probably not all of my friends would say the same) but you could not do trial-error programming and were obliged to think !

So I can say that I’ve written on paper quite a few pages of lisp functions :wink:

Sébastien.

3 Likes