syntax

God, I love lisp. Lisp to me is the eiptome of what good syntax is like. When developing in lisp, I tend to find myself pleasantly lost in its beautiful syntax.

Lisp’s syntax is single handedly the reason any programmer should atleast take a look at it. It is quite simple to understand aswell, I bet that a person who isn’t a programmer can easily pick up lisp as opposed to other languages…

In lisp, there are two types of data: s-expressions, and general values.

S-Expressions are basically function calls. They are inheritely a list of values preceeded by a function name.

For reference, this is how you’d print Hello World in Lisp.

(print "Hello World")

Contrast this to the way you’d print in a language like C:

printf("Hello World");

The difference is rather subtle when it comes to function calls. However, it gets more verbose as the language develops.

Take if statements as an example, in Lisp you’d call an if statement like so.

; t is equivlent to true
(if t
 (print "True")
 (print "False")

Again let’s compare to how c does it:

if(true) {
 printf("True");
} else {
 printf("False");
}

You see how C expands it’s syntax to support function body, that is a set of operations… But Lisp doesn’t and instead expands on it’s original syntax.

That is the key difference between Lisp and other languages. With Lisp, you return back to that same abstraction of s-expressions and values, where data is the same as code.

With Other Language, there is an awkward seperation layer between code and data. Which isn’t necessary harmful, but limits what you could do with the language…

transforming code?

In C, there is a simple yet powerful concept and that is the concept of macros. Macros are essentially placeholders for code.

Imagine you want to lessen the amount of verbosity in your code, so you create two functions:

  • MIN: which returns the minimum value
  • MAX: which returns the maximum value

You could theortically get by without such functions, but it would be very verbose and long. Here’s how you’d do it without a macro:

// MIN
x < y ? x : y
// MAX
x > y ? x : y

These two expressions evaluate the minimum and maximum value respectively. To shorten and re-use those expressions you could create the following macro:

// MIN
#define MIN(x, y) ((x) < (y) ? (x) : (y))
// MAX
#define MAX(x, y) ((x) > (y) ? (x) : (y))

So you could re-use it as such:

printf("min: %d", min(1, 2)); // 1
printf("min: %d", max(1, 2)); // 2

You could also accomplish the same with a function named min and max, but you’d need to specify the type of values that you want to compare.

Plus, you need to create different function names for each function with a different type. So In this case, macros are more simple and easier to use than a function.

Also, take a look at using the macros with more than 2 variables. For examples, 5 vairables.

printf("min: %d", min(1, min(2, min(-1, min(10, 3)))));

It’s messy, isn’t it?

With Lisp it is a lot cleaner and elegant. Let’s define a function in Lisp that returns the minimum value.

The reason we use a function instead of macros is because Lisp’s functions are that powerful. You could still have the same effect with a macro but it’s overkill.

(defun my-min(&rest values)
 (let ((min (nth 0 values)))
  (loop for val in values do
   (if (< val min)
    (setf min val)))
  min))

And then here is how you’d use it:

(my-min 0 -12 14 1.4 -20) 
; would return -20

Notice how cleaner Lisp looks compared to the C equivlent:

MIN(0, MIN(-12, MIN(14, MIN(1.4, -20))));

It is not a fault of C either, C++ has a lot of powerful features that allow for code generation. However, using them feels tacky and unelegant compared to Lisp. This is because Lisp falls back on its simple philosophy: Code Is Data.

It comes naturally to the Lisp developer to use & create these functions, but it is very unnatural to the C++ developer because often it adds more bloat to the language, more syntax rules and exceptions. With Lisp, you don’t. There are virtually no syntaxical exceptions(beyond Lists, Values, and Quotes) in Lisp.