What is Lisp?
If you've been programming for a while, you're probably familiar with a few programming languages, such as Python or JavaScript. Maybe you've heard of, or looked up Lisp before briefly. But what actually is Lisp, and what is it used for?
Lisp is a family of programming lanugages, whose name is short for list processor. Lisps are characterized by being composed of s-expressions (or sexps), which are forms surrounded by parenthesis. Common programming languages have both statements and expressions. Expressions return a value, statements don't. Sexps are expressions, it's in their name.
Okay, but why is that useful?
Because everything is an expression, operator precedence isn't a concern. Here's a simple math example:
In Python, you might write x = 4 + 5 * 2. At a quick glance, maybe you forgot to apply PEMDAS and ended up with 18 instead of 14 because you just quickly read left to right. That's fine, what if you actually wanted to do math that way? We can, but we'd have to write it as x = (4 + 5) * 2. I hear you think I know how to do math, why are you telling me this? In short, it's not just math that this affects, but first: let my introduce the Lisp way. Lisp uses Polish Notation (or Prefix Notation) which avoids the issue of the problem that parenthesis change the meaning. x = 4 + 5 * 2 would be translated as (def x (+ (* 5 2) 4)) and x = (4 + 5) * 2 simply as (def x (* (+ 4 5) 2)).
You know how I mentioned it's not just math this affects? I'm going to give a real example I encountered earlier today. Let's compare the following Python and Raku snippets. Huh? The Raku snippet prints 1? Why? In Raku, the `=` operator has higher presedence than the `,` operator [3].
a = 1, 2
print(a) # (1, 2)
my $a = 1, 2
say($a) # 1
In Clojure, this would be:
(def a '(1 2)) ;; the quote operator prevents evaluation of the form (1 2)
(println a)
*But isn't it weird to evaluate the innermost form first?* Intitially, yeah, but you get used to it, and if not Clojure has this cool construct called the thread-first macro [4]. This lets you write math closer to how you're used to:
;; x = 4 + 5 * 2
(def x
(->
(+ 4 5)
(* , 2))) ;; commas are whitespace
A/N: In Clojure, it's fairly common to use macros provided by the standard library, with writing your own being somewhat discouraged. Because of this, they won't really be in scope of this article, but they're powerful tools that transforms the representation of your code. I may write a separate article on them in the future.
Where is Clojure used?
Clojure is commonly used for web development and has the famous Ring compatible ecosystem. As a benefit of being a JVM hosted language you even get access to every Java library! There's even a variant of Clojure that compiles to JavaScript aptly named Clojurescript.