Should I Learn Common Lisp?

preview_player
Показать описание
Should I learn Common Lisp?

Common Lisp or CL is one of the founding programming languages. It has been around for as long as we've had computers, since the 1950s.

I've heard you should learn it because you learn how to program in it.

The hard part is that once you've learned to program in Common Lisp, you have trouble learning the logic behind object oriented programming or even some functional languages.

Common Lisp supposedly teaches you a pure functional process.

Purity should only refer to the clarity of your cell phone connection or beauty of the digital image. Software code has to handle exceptions, errors and the oddities of dealing with people.

You don't think we should use Lisp.

You could learn Lisp if you really like parenthesis and obsessive compulsive tracking of code, given how functions get scattered throughout a Lisp code module.

There are huge libraries of Common Lisp code.

And Emacs has around a million lines, but that doesn't mean it is any good.

It has a long history.

If you want technology based on history, go talk to the Amish.

I've heard that Common Lisp may be ugly, but it is very powerful.

You've been reading Paul Graham's blog. He is pretty much the only powerful blogger promoting Common Lisp online.

You don't agree.

Most of the websites, browsers and phones accessing his site use Java, JavaScript, Python, C or some other language. There might be a Linux guru reading his pro-Lisp page on a jerry-built computer running Lisp based interfaces and code.

There are companies programming in Lisp, like Autodesk.

Which is why Pro-Engineer by PTC is dominating it.

What should I learn instead?

You could learn Scheme or Clojure. Heck, C and Python are just as good and more likely recognized by the person who reads your resume one day.
Рекомендации по теме
Комментарии
Автор

CLOS(Common LISP Object System) is a more feature complete OOP design, than that of C#\Java. The difference is that C# and Java enforce an OOP design, where as in CL it is optional(same as Python and C++). There are entire books written about CLOS that rival C#\Java's OOP books in complexity and size. Java\C# would make you a worse programmer as you force everything to be an object, even things that shouldn't be. Python, C++ and LISP does the opposite, it allow you to use the right tools for the right job.


The average OOP student will create functions that does a LOT of things. Which increases the odds and chance of unwanted results exponentionally, and makes it exponentionally more difficult to find these issues. Just as not everything should be an object, not everything should be purely functional. You need the balance of all things. A universal rule of thumb however, is to never have a function do more than ONE thing, doing more than one thing increases the chance of not being able to find that one thing that goes wrong. If you have 5 functions doing 1 thing, and thing #3 isn't working, you know function #3 is at fault. one function doing all 5 things, you know the function is at fault, but you'll have to go through a nightmare of debugging to identify what exactly went wrong, rather than just looking directly at the primary cause.

--

"Programming languages need to be able to handle the errors when dealing with people" - Lisp doesn't have an exception system, this is true. However it does allow you to dealing with errors just fine. 1: you can recreate an exception system if you really, really want to(we don't, because lisp allows better error handling tools by default, than exceptions do) 2: Because of the way lisp handles errors, you can fix whatever caused the error in runtime, there is no reason to suspend the running of the program, ever. Unless you want to (in which case, you can enforce a shutdown on errors you haven't explictivly made exceptions for).

CL is more akeen to C in this, in that you'll make your own error cases using If\else statements, rather than making different catch-all exceptions. If you forgot about it, again the program will not stop it's operation, but allow you to define the thing the program is looking for(wether it be a variable, a function, or an incorrect datatype), but as stated, you do have the ability to hijack the error-case system and re-create Java\C#'s exception system, if you really wanted to(it wont' take you that long, just hijack and check the cause for errors, then make an cond check and check which type of error was sent).

--

"You can learn lisp if you really ---" - This is how we know you've never actually coded in lisp in any serious capacity. Maybe just had to do an assignment, or sit through a lecture of it. You don't have to possessivly keep track of your code, at all. Or at least, not anymore than the average programming language: "but in C# I can click a function and be ported directly to where this function is defined!" - that's the case of the IDE, not the language. You could recreate this exact same thing in Emacs, if you really want to. If anything, lisps functional programming style makes it easier to keep track of what does what, and how. OOP design makes code far less readable, as everything is a class with methods, so you need to remember what class does or have what method, rather than just keep a global call of all of them.

To keep track of where your functions are, you have seperate files to keep them bundled up(I know, madness! Since in Java\C# this isn't an option, all source files lead to exactly one class, anything else is bad programming style in OOP, because of this, you might end up with a thousand lines long code in one class. That's hardly readable if you ask me(this is why Visual Studio allow you to port directly to a function definition, browsing through your classes becomes difficult quickly, it is unecessary clutter).


You could make a case that CL's packaging system is awful, as it is. But Quicklisp and ASDF(comes together) changes this and makes CLs packaging system rival that of Java\C#.


--

These are some things invented with LISP: Garbage Collection(Oh look, this ones important! So much so every modern language have it!), Free variables that doesnt' need to be defined(Something C-derived languages always love, yet it is unecessary and cause unecessary overhead), big numbers(lisp have always had "big numbers" as a standard, dynamically allocating memory as needed for your variables \ numbers, this is something imperative languages didn't really see until Java), Lambda(undefined functions, this is such an important feature that even Java, that hates these kind of smart design decisions, decided to implement it!), Applicative programming(PHP has this, Java does not or at least didn't last time I used it years and years ago, C# might, but I doubt it, C\C++ does not), Macros(only other language I know that has Macros is Perl. Marcos is important in that it allows you, the programmer to have far more control over the language. With C#\Java\C\C++, you are on the mersy for what the creators have decided to implement, you can't just implement your own features, in the language. That's what macros allow you to do, and why it is such a "big deal"), Hash-tables(this was originally developed in lisp for lisp, it was such a good concept it got added into other languages later), for x in list - this kind of looping has it's origin in LISP.

Now I might be wrong, but I remember reading or hearing about how Regex was directly inspired in how some LISP-implementations did things(Format function comes to mind, it's basically a different type of regex focused on printing).


But the biggest, BIGGEST two things of lisp is: 1: Data and code is the same, there is no direct seperation between code and data. Not the case in majority of languages(PHP being an exception). This is also why Macros work so great in lisp, and why Lambda and applicative programming is in LISP, and so important. You can do whatever you want, at any time, as code and data has no seperation layer. Data is just non executed code(which you can define to be executed). This is why you need to do this in python fun(s, d, g), while in lisp you can just do (fun s d g), there is no need to define formating, or enforce seperations, because you know that every element after fun is going to be a seperate parameter, and that fun is the function. Always.

2: repl. The repl allow you to code while your program is running, this is something you can't even do in Python, and Python is not a compiled languge(lisp actually is, but different way to C\Java\C#). For instance, while you are making a video game and you wanna do some quick athestic checks to see how it'd look if something was less, or more of etc. In python you make the chance, open the game, don't like it, close the game, make adjustment, start again, and so on. in CL? You make the change, compile the code, and it'll immediatly show up. Making changes is far easier using LISP, than it is using other languages.

Bonus: Lisp is in paranthesis because of it's S-expressions(Everything is a list, and is represented as a list). Other languages use M-expressions(which is better represented as everything being strings\text). Imperative languages lack many of lisps features, such as data and code being equal, because it is more complicated to code that out using M-expressions. S-expressions however was basically designed for this.

SknCommonLisper