Previous Post
Lisp Syntax and You
Ok, so I’ve actually had a chance to start into the book now that Emacs isn’t so much of a drain. Now I have gone a round or two with Scheme, so the idea of Lisp isn’t that far out for me, but I can’t promise I have the best explanation of why Lisp is… well why Lisp is Lisp. In short, Lisp is build off lists. The name Lisp is short for List Processing, and trust me it’s not just another clever name. I can basically describe you the 80% of what Lisp is in one text diagram:
(operation value1 value2 value3 …. valueN)
And that’s basically it. The very first item in the list is what needs to be done. This can be something like the + symbol that means apply + to all the items in order. So:
(+ 1 2 3) actually means 1 + 2 + 3
So the first thing you might ask, and even if you wouldn’t I’ll still assume you did: What if you want to add something to something else that is in itself added to something. Sorry, that’s my mind trying to ask your question, and it made more sense in my mind. In other words, something like this:
(1 + 2) * (3 + 4)
How is that possible if the first part of the list is the only operator? In that example, it doesn’t make sense, because it’s not in Lisp form.
(* (+ 1 2) (+ 3 4))
As you can see it breaks down to more lists with more operators BUT it does not break the golden rule: Operator Value Value. And honestly, that’s most of the language. There are a few, very few relative to most languages, “special forms” as they’re called, but what that really means are things that break the Operator Value Value rule. As far as Lisp is concerned, I have only run into the most basic of them:
(defun method-name (parameter) (method body))
As you can see, this sets the symbol “method-name” to represent a function body. There’s also:
(setf some-name some-value)
Which again attaches a value to some-name. I do know of more since Scheme works the same-ish way. (I’ve put a little time into Scheme) It has “special forms” like if, cond, and so on, but I’ll comment on them when I hit them in Lisp. The important thing to take away is that pretty much all of Lisp’s structure follows the same damn rule. In this way, it make it fairly easy to interpret from a human side once you get used to all the ().
&@*# the parentheses
I can pretty much guess that if you’ve never seen Lisp, you’ll see all the () and want the get the #@$% off the bus. I get that. It is kind of odd, but in the end there are two things that may help with that:
1) The () helps to interpret it in the long run. After all, from reading what I did above you know that anything between ( and ) follows the rule Operator Value Value right? Well take that a little farther in the example of the more “complex” math thing.
(* (+ 1 2) (+ 3 4))
I know exactly what this will evaluate BECAUSE of the parentheses. I know that every time I see a ( that anything within that ( will be evaluated on it’s own. No question. And for every new ( I know there is something that will be evaluated within that (. This helps to encapsulate functionality for easier breakdown.
2) I personally *#@$ing hate { } and ;. They drive me nuts. After I used Python a while back (and Nemerle and F# and Coffeescript), and as a consequence I got really tired of { } ; in C#. Yeah, there are a lot of (), but that’s all that there are. Just like how Lisp follows the rule of Operation Value Value, it also has syntax uniformity. Would I be happier if Lisp used whitespace? After some thought, no. Why? Because I’m not sure that’s even possible, and it would completely break the ease of interpretation. After all:
*
+ 1 2
+ 3 4
Just doesn’t read too well. Also, even languages like F# need (). Why is that? Because of evaluation:
let someMethod x y =
x + y
Simple enough right? What if x is a method call?
someMethod someOtherMethod 1 2 3
F# will choke because it will try to shoehorn someOtherMethod into x and 1 into y leaving 2 3 as a source of confusion.
someMethod (someOtherMethod 1 2) 3
Hmmm… looks kind of familiar. Only difference is that it gets annoying having to switch from no () to () in F# due to how it evaluates arguments. At least with Lisp you get uniformity. Now I’m not expecting to sell you on anything at this point, because I haven’t really gotten into anything good. However, I do know that there are some very profound things to come due to watching the SICP videos. Mainly two simply brilliant words (that of course I can’t remember at this moment so I have to check my twits) “Wishful Thinking”. That phrase was the very one that made functional programming make complete sense, and this was after I thought I really had a firm understanding of functional programming.