Interesting article, introduced me to a whole bunch of lisps I had no idea existed.
Slightly tangentially, can anyone explain to me what the supposed advantage of using Lisp is over languages such as Python and Ruby (which also provide functional programming, dynamic typing, etc)? I certainly feel that I'm more productive in some languages than others, eg, I can do the same things faster in Ruby than in Java. When I tried working in Clojure for a few mini projects, I enjoyed using it, but didn't feel any more productive than in Ruby.
I actually like the Lisp-like syntax, but I usually find myself either a) tying myself in knots trying to avoid the use of variables, or b) missing Ruby's object system. It seems like these might be problems that stem from inexperience, can anyone else comment? Is it worth reading "On Lisp" or SICP to learn how to take advantage of Lisp's unique features (macros and so on)?
There are some things that are actually quite difficult or simply impossible to express in Ruby, Python, and other mainstream OO languages. The promise of Lisp has always been (to me at least), powerful runtime dynamism without sacrificing performance, I wrote about this yesterday, http://dosync.posterous.com/51626638.
It's also quite difficult in my experience to explore and implement more sophisticated and powerful OO and FP concepts like predicate dispatch (think CLOS generic methods or ML pattern matching but more useful) or ad-hoc type systems in these languages - especially when your goal is to produce something that is not a toy. Or think about embedding an efficient logic programming DSL a la Paradigms of Artificial Intelligence.
Of course for various reasons, that this kind of flexibility and power can be applied to real software development might not interest you. But it is why I find Lisp compelling.
Turing completeness says absolute nothing about performance. If my embedded logic programming library takes 2ms to run a query and yours takes an hour - I can actually put mine to useful work.
Granted many languages simply move this kind of work to external C dependencies and such. However this doesn't address the other kinds of language extension such as idiomatic ad-hoc type systems and predicate dispatch I mentioned.
Why shouldn't our programming languages capture these heterogenous use cases comfortably?
Ah, yet another misapplication of the "Turing completeness" idea. Turing completeness is about results, not methods of computation. If two languages are said to be Turing complete, it means that they are able to compute exactly the same set of functions, and not that they do it in exactly the same way. For instance, you have a problem that in one language is solvable in O(n), but in the other it provably requires Omega(n lg n), because certain constructs (e.g., random-access arrays) are missing from it.
Kolmogrov complexity proves that while language A can emulate capability X from language B, it is impossible to do so without writing B in A. In which case, it is still B doing X.
So, in a literal sense, it can be impossible to do X in A and possible to do X in B, even though A and B are Turing complete.
Of course it's possible. The question is; how much work is it going to be? Will I have to use my turing complete language to implement Lisp to do it? In that case I would accept "impossible" as shorthand.
Many people ask the same question(about lisps advantages), expecting a big list of features that will magically make their life instantly easier, i have no such list, but many people claim to do, and you can find them with some googling(i think theres one clojure specific on their site :).
Instead I'll just give you a few words about what value I've gained by learning scheme, clojure and common lisp. This is personal, and specific to me :)
Scheme taught me the basics of CS, It is an exceptionally good teaching language, when ESR said that lisp was worth learning because of the enlightenment, he probably meant(or should have) scheme. I've never actually used scheme for anything, so i won't talk about how actually useful it is.
After scheme i got into clojure, about the time 1.0 came out(i think?). For me, theres a lot to love and a lot to hate in clojure. I loved this language, It took the stuff scheme taught me, and showed me how to actually use them well. It made me think, it made me learn, and it made me get better. It didn't make me better, i made myself better inspired by it(same is true of all lisp i know actually). I ultimately concluded that clojure and i are headed in different directions, so we parted, but I'm sure our paths will cross again, when are both better.
Now common lisp is something special. Everything i said about clojure applies to common lisp. The languages are very different, but the end goal is the same: good software. Common lisp taught me how much of what i took for granted was just contemporary fashion trends, it showed me that theres value in knowing the history of lisp well, it showed me that i had accepted the front page of HN as what reality was like, and freed me of this world view. It showed me that software truly CAN be good if I put in the effort to make it that way.
I no longer blame my tools for my failures, because it is I who chose them, and I who used them. This attitude is maybe the most valuable thing i got from learning lisp, just fucking do it, because you can. And it pisses me off when people claim lisp can make you more productive, it won't unless you learn it well and use it wisely.
It depends who you ask. I'm also a beginner in lisp. Wrote some hobby projects in it but it felt like swimming against the current.
lisp appeared a long time ago, when non lisp languages were really primitive. So a lot of the arguments you might read on the net might be outdated (comparing it to C or FORTRAN).
Ruby and Python give you a lot of power that a lisp language has. I guess the only thing that lisp has, which the other languages don't, is the "macro". Which (in my opinion) is like a lisp "program" running before your lisp get compiled and changes the code. So several lines can be expanded to lots of dynamically generated code.
C guys will say they have #define & such, but this is a "program" with most of lisp syntax not just some primitive ifdefs. So you can do a lot of advanced stuff.
On the other side, python & ruby have a lot more libraries. I see that common lisp has picked up steam again, with stuff like quicklisp which can be seen as "ruby gem".
So to sum it up, lisp is a powerful language, it has constructs which are still not available in other languages but you don't get the free stuff you would have in big communities as python or ruby.
Actually theres soo much in common lisp besides macros that i miss in addition to them when i have to work with python, like CLOS, the condition system, format, the lisp reader/printer(using JSON is only half a solution), good performance, and with paredit mode for emacs i can edit code a lot easier than with python.
Also your summary, python and ruby's libraries are not free, because you have to use python or ruby instead of common lisp. That is a cost of some kind, a trade off, is it not?
Lisp has a lot more than just macros (also you might want to learn more about macros; your definition is a little off).
You also get CLOS; which is huge. Multi-methods. Generic functions. MOP. OO programming without generic functions is a huge pain for me now. It's a completely different world-view that lacks very artificial design patterns. You don't need a lot of the GoF design patterns because they're completely abstracted out by the language of CLOS.
You get conditions and restarts. I hate exceptions! You lose the entire stack and state of your application. It is next to impossible to recover from that and restart the failed computation using exceptions. You could emulate this in other languages... but it's already a part of the Common Lisp language itself. No code to write or libraries to import to make it happen.
And only tangentially related to the CL language itself, SLIME is another reason why programming with Lisp is a lot of fun.
So to sum it up, lisp is a powerful language, it has constructs which are still not available in other languages but you don't get the free stuff you would have in big communities as python or ruby.
If you're writing a programming language, Lisp's terse syntax makes writing the boring parts like the parser very simple. That's why many of these cool projects use it.
But for the more everyday tasks, other languages work just fine. Lisp isn't always going to be a big productivity win over Ruby or Python. If you're looking at it from that angle, you'll be disappointed.
But yes, it's worth reading On Lisp and SICP, and working through the examples. Afterward you'll find yourself missing features that Lisp has when you work with other languages; at that point you can make an informed decision which one fits your problem best.
I think you would struggle (at least initially) to feel more productive in Scheme than Ruby / Python (although Racket seems like it would probably be equivalent to Ruby/Python in capability).
However, I'm concentrating on Common Lisp these days, and there are things about it (it's object system (CLOS) and probably macros) that feel much more flexible and productive than even Ruby or Python.
Here is the order of books I'd recommend if you want to explore Common Lisp:
1. Land of Lisp by Conrad Barski
2. Practical Common Lisp by Peter Seibel
3. ANSI Common Lisp by Paul Graham
4. On Lisp by Paul Graham (available online)
5. Paradigms of Artificial Intelligence by Peter Norvig
Then maybe:
6. Art of the Metaobject Protocol
I mostly agree with tdrgabi, and I think Python has a big advantage over the Lisps I've used (Common Lisp and Racket) in its "batteries included" standard library. Plus, Python is more readable and has powerful list comprehensions that make it competitive with Lisp in expressiveness in most cases. And, of course, the biggest advantage of Python or Ruby over Lisp is political -- if you hand off a well-written Python script to your coworker and he complains about you using Python, then he looks like an idiot instead of you. Try that with Lisp.
However, I think Common Lisp and Racket have two big advantages over Python. Number one is performance. They're dynamic, but they're also compiled, which means they can be big and featureful when that's what you want (e.g., CLOS) but they can be fast when you need them to be. I haven't tried this in Racket yet, but when you're optimizing a function in Common Lisp, you can ask the REPL for the compiled form and it will spit out the assembly. You can tweak the safety and optimization settings, recompile the function, and look at the assembly again. Iterate until you eliminate whatever is killing your performance. Python lets you call out to C, of course, but so do Common Lisp and Racket.
Number two is the development experience. The typical workflow is to set up a running instance of Lisp, connect to it from your editor, and then send code to it. You can write a bunch of code in your editor, highlight a couple of functions and send them to your Lisp instance, and then play with those functions in the REPL. Need to tweak something or fix a bug? Edit a function and send the new version to the Lisp instance. Then see how it works. Maybe you can do the same thing in Python with the correct setup. If so, I'd love to hear it. (I'm sure it's possible with some Python IDE or other, but why give up your favorite text editor?)
Number three, if it came into play more often, would be that Lisp really is more expressive than Python. Honestly, I almost never see the difference in the work I do for a living. The more interesting the problem, though, the more likely you are to see a difference.
fwiw, Racket is byte-compiled and run on a VM with a JIT compiler for optimization.
Depending on the implementation, you can get machine-code from Lisp by way of an optimizing compiler or you can get just the interpreter.
There is a lot that Common Lisp has that is heads above Python in terms of features (CLOS, numerics, streams, macros). The implementations can offer even more (threading, optimized machine code, GUIs, etc).
Racket offers its own features and benefits. It has a great built in library, you can package languages as libraries, it has a great module system and public repository...
Python, Lisp, Ruby... they all have their features and trade offs.
Maybe you can do the same thing in Python with the correct setup.
You can with Emacs, pdb, iPython, virtualenvwrapper, and a few emacs-lisp scripts. It's nothing compared to CL+Slime, but it's pretty good. I use it in my day to day work.
You have it exactly right, I think: Lisp's advantage is the interactive repl environment. I do a lot of work with NLP and keeping a (SBLC) Lisp image with all required data loaded saves a lot of time. Even if I am not working in the mode of keeping pre-built images around, starting up an environment and not having to restart it saves a lot of time. I really love to code in Ruby, but the repl experience is better in Lisp.
What makes Lisp unique, in my opinion, is its elegant unification of code and data. The 'eval' function and of course Lisp macros are very powerful features that come out of this immediately, and theoretically you can implement any other language feature on top.
In most other languages, to do the same things you have to parse the syntax, build an AST (Abstract Syntax Tree), do whatever transformations you need, and if you're very lucky you can then call the compiler as a library. Lisp makes the AST directly executable with 'eval', and provides a syntax parser already. Moreover, the AST is made of lists and symbols, which Lisp is naturally perfectly suited to manipulating.
All this makes Lisp quite beautiful as a mathematical object. I can't speak on its practicality ;)
You might try common lisp then, as it has an object system (CLOS), and does not enforce functional purity. The one downside is that a lot of people like to complain about it, for reasons that don't really make sense to me.
The first advantage is that you can use the entirety of the language at compile time. (This means you can use CLOS, structs, functions, methods, anything). Basically what this gives you is an easily programmable compiler.
The second advantage is that programs written in common lisp can be very fast. The compilers in general are very mature, and tend to compete with speeds of languages like C and C++ when properly optimized. In addition to proper declarations, if you know what a C compiler would do to make a bit of code run fast, you can easily duplicate it. You also have clever/tricky things like eval, with which you can (for example) use run-time information to re-generate a piece of code in a better optimized way.
The third advantage is that I like the syntax, it is simple, and I don't have to fuss with balancing different types of brace or worry about order of operations.
I've never read SICP personally, my impression is that it is much more focused on the principles of computer science than it is on lisp or scheme, generally. Nowadays to learn I might start with practical common lisp or one of the Clojure books, and then move on to one of the more advanced books, like 'On Lisp' or 'Let over Lambda.'
I'll get burned at the stake for saying it, but there isn't really a lisp 'style'. (A lot of people will tell you there is). Just start writing programs that work with pieces of the language that you know (in common lisp there is some redundancy), and eventually you'll have enough knowledge of the language to have a reasonable style. You can fix it to be pretty later (or not, I call this the PHP approach).
There is a ton of information on line in HTML and PDF form, also, many of the older books have been released into the public domain on line (on lisp being an example) Just use google and they should show up.
It also helps to learn a bunch of other languages, I regularly steal convenient idioms from other languages and implement them as macros.
Ruby programmers love domain-specific languages implemented in Ruby (eg RSpec). A Lisp dialect lets you implement libraries with fewer restrictions on what the DSL can do and more expressive power. Lisp takes Rails-style succinctness through metaprogramming to the next level.
I've done a bit of programming in lisps and scheme, and have recently been working on a ruby project. While I enjoy ruby, I'm finding it difficult to reason precisely about the code I write in it, because the semantics are so complex and everything is so dynamic and fragile. It makes me anxious as a build and add complexity.
With lisps and other languages like haskell, the semantics are extremely simple.
That's probably pretty vague, but it's another perspective.
While I've heard a number of justifications for Lisp, based on feature A or B, to me the power of Lisp is pretty simple.
Essentially, lisp is the parse tree that all other programming languages convert their syntax into.
This means that all language features can be embedded as DSLs in Lisp using its macro system. No other language I know of can do this as conveniently as Lisp.
I just retweeted Michael's tweet link this blog entry - this is really a very good classification of Lisp systems! It could be a potential time sink however, trying more implementations :-)
This is very cool; I wasn't aware of the existence of some of these implementations.
The Wasp Lisp is an interesting idea and looks like it has many of the same benefits as Erlang. If I had to guess at what programming languages would look like in the future I'd say they'd at least include capability to (easily) do distributed computation like this, even if they're not based around the concept.
There are so many qualities that Lisp has, like its lack of syntax, that makes exploring new ideas very easy.
I just spent a few hours searching but can't find a Lisp for Arduino. Does anyone know a Lisp for Arduino or a Lisp that could produces C code small enough (<32K) for it?
After some tries neither Chicken scheme nor Pico Lisp qualifies and PicoBit does not seem to support the Arduino architecture.
Slightly tangentially, can anyone explain to me what the supposed advantage of using Lisp is over languages such as Python and Ruby (which also provide functional programming, dynamic typing, etc)? I certainly feel that I'm more productive in some languages than others, eg, I can do the same things faster in Ruby than in Java. When I tried working in Clojure for a few mini projects, I enjoyed using it, but didn't feel any more productive than in Ruby.
I actually like the Lisp-like syntax, but I usually find myself either a) tying myself in knots trying to avoid the use of variables, or b) missing Ruby's object system. It seems like these might be problems that stem from inexperience, can anyone else comment? Is it worth reading "On Lisp" or SICP to learn how to take advantage of Lisp's unique features (macros and so on)?