Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm not sure, if some weird things make my Code faster:
Is it normally better to use inbuilt operations or write new specialized functions, that do the same thing?
(for example a version of #'map only for vectors; my version is often faster without type declarations)
Should I define new (complicated) types to use them in declarations?
(for example a typed list)
Should I define slots directly to an object? (for example px and py for a 2-dimensional object, or is it ok to use one slot pos of type vector, that I could reuse it for other purposes)
There are a few parts to this but here is a quick braindump
PROFILE!
Use a distribution of CL that has a profiler built in, I use sbcl for example http://www.sbcl.org/1.0/manual/Statistical-Profiler.html
The nice thing about the sbcl profiler is that once you have profiled a function, if you disassemble it, the machine code is annotated with statistics. This requires some knowledge of the target machine code.
Do not underestimate your implementation: They can have advanced type and flow analysis built in and are able to, for example, pick a vector only version of map when it makes sense.
Learn compiler macros: compiler macros can shadow functions this gives you a place to put extra optimizations based on the context of the form. IT does this without replacing the function so it can still be used in a higher order way.
Learn Type declarations
I found this series of blog posts helped me understand this technique http://nklein.com/tags/optimization/page/2/ Read em all!
ONE MASSIVE NOTE: Don't ever lie to your compiler about a type. Type declarations are a way of telling your compiler you know what the type is the compiler doesn't even have to use them, and when it does it doesn't have to check you are giving it the correct thing.
Unboxed data
Some implementations are able to unbox certain datatype in certain conditions. Sorry that is vague but you will need to read up for your implementation. For sbcl the 'sbcl internals' guide is very helpful.
For example:
(make-array 100 :element-type 'single-float :initial-element 0.0)
Can be stored as a contiguous block of memory in sbcl.
PROFILE AGAIN (With realistic data)
I spent 3 hours writing a crazy compiler macro based n dimensional matrix multiplication routine and then tested it against a 1 line built in solution. For matricies below 5 dimensions there was not a big difference! For higher dimensions, yeah It rocked but that 'performance benefit' is purely academic because those code paths were never touched. Luckily I undertook the task for fun as I was asking the same question you are now.
Algorithms
All the type specifiers in the world won't give you a 100times performance increase. This comes from better techniques. Read on the maths behind the problem, implements different helper functions that have different strengths and choose between them at runtime...then go back and use compiler macros to allow lisp to choose at compile time. OR specify the technique as a higher order functions, for example make-hash-table allows you to specify the hashing function and rehash sizes, this can be crucial in getting good performance at certain sizes.
Know the limits of BigO
Algorithmic complexity means nothing if you loose all the of performance due to memory locality issues. Conversly sometime we can achieve superlinear performance characteristics if, by spliting the problem among cores, the reduced dataset now fits in the l2 cache.
BigO is a great metric but it isn't the end of the story. This is the reason assoc lists are a totally valid alternative to hash-tables for low numbers of keys and certain access profiles.
Summary
There is a golden mantra I heard from somewhere in the lisp community that works so well:
Make it Fast and then make it Fast
If nothing else follow this. Chant it to yourself!
Get the program up and running quickly, in doing so you are more likely to spot the places where you can use a better technique or algorithm to get your several-orders-of-magnitude improvement. Do use CL's own functions first. Don't trade lisp's higher order nature too early by using macros, explore how far you can go with functions.
[Edit] More notes - the following is for sbcl
Type definitions on struct slots are used for optimizing, type declarations for class slots are not.
With regard to types, start with what makes the program easy to write and understand (Make it fast) and then look into access times if it is the bottleneck (make It Fast!)
(slot-value x 'name) is very fast when name is known. Look at how with-slots uses symbol-macrolet to it's advantage
So to kinda directly answer your original question:
built in first (also check libraries)
does it make the problem easier to write and understand?
use pos. By the time the performance of that indirection becomes and issue you will have found a dozen other ways to speed up the problem and the solution will be part of a wider optimization technique.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I would like to learn a functional language in order to broaden my horizon. I have knowledge of Python and C/C++ and I want a language to be easy to learn from someone who comes from the imperative domain of languages. I don't care if the language is powerful enough. I just want a language in order to learn the basic of functional programming and then I will try for a more difficult (and powerful language).
Thanks
I recommend pure-lang for these pedagogical ends. It's also plenty powerful. If you want something more popular / with more community support, then I'd recommend Scheme or OCaml, depending on whether you'd rather deal with unfamiliar syntax (go with Scheme) or deal with unfamiliar typing (go with OCaml) first. SML and F# are only slightly different from OCaml. Others have or will mention Clojure, Scala, and Haskell.
Clojure is a variant of Scheme, with its own idiosyncracies (e.g. no tail-call optimization), so using it would be a way of starting with Scheme. I'd expect you'd have an easier time with a less idiosyncratic Scheme implementation though. Racket is what's often used for teaching. Scala looks to be fundamentally similar to OCaml, but this is based on only casual familiarity.
Unlike Haskell, the other languages mentioned all have two advantages: (1) evaluation-order is eager by default, though you can get lazy evaluation by specifically requesting it. In Haskell's the reverse. (2) Mutation is available, though much of the libraries and code you'll see doesn't use it. I actually think it's pedagogically better to learn functional programming while at the same time having an eye on how it interacts with side-effects, and working your way to monadic-style composition somewhat down the road. So I think this is an advantage. Some will tell you that it's better to be thrown into Haskell's more-quarantined handling of mutaton first, though.
Robert Harper at CMU has some nice blog posts on teaching functional programming. As I understand, he also prefers languages like OCaml for teaching.
Among the three classes of languages I recommended (Pure, Scheme and friends, OCaml and friends), the first two have dynamic typing. The first and third have explicit reference cells (as though in Python, you restricted yourself to never reassiging a variable but you could still change what's stored at a list index). Scheme has implicit reference cells: variables themselves look mutable, as in C and Python, and the reference cell handling is done under the covers. In languages like that, you often have some form of explicit reference cell available too (as in the example I just gave in Python, or using mutable pairs/lists in Racket...in other Schemes, including the Scheme standard, those are the default pairs/lists).
One virtue Haskell does have is some textbooks are appearing for it. (I mean this sincerely, not snarkily.) What books/resources to use is another controversial issue with many wars/closed questions. SICP as others have recommended has many fans and also some critics. There seem to me to be many good choices. I won't venture further into those debates.
At first, read Structure and Implementation of Computer Programs. I recommend Lisp (for, example, it's dialect Scheme) as first functional programming language.
Another option is Clojure, which I'm given to understand is more "purely" functional than Scheme/Racket (don't ask me about the details here) and possibly similar enough to let you use it in conjunction with SICP (Structure and Interpretation of Computer Programs, a highly recommended book also suggested by another answer).
I would like to learn a functional language in order to broaden my horizon. I have knowledge of Python and C/C++ and I want a language to be easy to learn from someone who comes from the imperative domain of languages. I don't care if the language is powerful enough. I just want a language in order to learn the basic of functional programming and then I will try for a more difficult (and powerful language).
Great question!
I had done BASIC, Pascal, assembler, C and C++ before I started doing functional programming in the late 1990s. Then I started using two functional languages at about the same time, Mathematica and OCaml, and was using them exclusively within a few years. In particular, OCaml let me write imperative code which looked like the code I had been writing before. I found that valuable as a learner because it let me compare the different approaches which made the advantages of ML obvious.
However, as others have mentioned, the core benefit of Mathematica and OCaml is pattern matching and that is not technically related to functional programming. I have subsequently looked at many other functional languages but I have no desire to go back to a language that lacks pattern matching.
This question is probably off-topic because it is going to result in endless language wars, but here's a general bit of advice:
There are a class of functional programming languages which are sometimes called "mostly functional", in that they permit some imperative features where you want them. Examples include Standard ML, OCaml, F#, and Scala. You might consider one of these if you want to be able to get a grip on the functional idiomatic style while still being able to achieve things in reasonably familiar ways.
I've used Standard ML extensively in the past, but if you're looking for something that has a bit less of a learning curve, I'd personally recommend Scala, which is my second-favourite programming language. The reasons for this include the prevalence of libraries, a healthy-sized community, and the availability of nice books and tutorials to help you getting started (particularly if you have ever had any dealings with Java).
One element that was not discussed is the availability of special pattern-matching syntax for algebraic datatypes, as in Haskell, all flavors of ML, and probably several of the other languages mentioned. Pattern-matching syntax tends to help the programmer see their functions as mathematical functions. Haskell's syntax is sufficiently complex, and its implementations have sufficiently poor parse error messages, that syntax is a decent reason not to choose Haskell. Scheme is probably easier to learn than most other options (and Scheme probably has the king of all macro systems), but the lack of pattern matching syntax would steer me away from it for an intro to functional programming.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Why would one use a functional language in an otherwise Imperative project?
Many tasks are inherently addressed by functional concepts, such as composable calculations. It is feasible that you will encounter these kinds of problems in projects which have otherwise been developed in an object-oriented fashion.
The best tool for a job is independent of that tool's dominant paradigm.
If your project is truly imperative, you probably don't want a purely functional language. But you probably still want a language with functional features; functional style addresses low-level code structure in the same way that object-oriented style addresses high-level structure. Both allow you to package certain common patterns in a language-supported way.
In a primarily imperative project, functional style is useful at the expression and statement level, allowing you to abstract common loops and sequences:
For example, take this common pattern:
newlist = []
for x in oldlist:
y = dosomething(x)
newlist.append(y)
That's map:
newlist = map(dosomething, oldlist)
Or this:
total = 1
for n in numbers:
total = total * n
Becomes fold (also known as reduce):
total = fold(*, 1, numbers)
Imperative style does not address this low-level duplication all that well--hence the "I wish I had a nickel for every time I typed for(int i = 0; ...)". Even in OO languages without functional features, code inside methods doesn't differ much from similar non-OO languages.
Some IDEs for address this by providing code snippets. This addresses the lack of abstraction power in the wrong way. The way to handle a repeated pattern is not to encourage cut-and-paste with little holes for variable names, but to abstract the pattern into a reusable unit.
Note: I addressed embedding functional code in an imperative project. A top-to-bottom project in functional style will look different. Here are some links taken from similar Stack Overflow questions:
http://www.25hoursaday.com/weblog/2008/06/16/FunctionalProgrammingInC30HowMapReduceFilterCanRockYourWorld.aspx
http://www.joelonsoftware.com/items/2006/08/01.html
Many methods in languages like Java and C++ could be written in a more readable and dense form using FP concepts such as higher-order functions, currying, closures, etc.
See Scala for many interesting examples.
Probably, the most common reason - is to localise and restrict the imperative part (i.e., potentially dangerous and harder to debug, analyse and maintain).
A common problem faced by application developers is building queries: "I want all customers over the age of 18 who have spent $10K in the past year." The process of defining a query that returns all customers, then filtering it by one criterion, then another, and finally a third, is called composing the query. Composition is a strong suit of a functional approach, meaning the query definition problem and a functional solution are well-matched. To see this in action in a popular object-oriented language, see C# and LINQ
Why would one use a functional language in an otherwise Imperative project?
Some examples:
The Mathematica kernel is written in a proprietary dialect of C. Mathematica is a functional language so it makes it much easier to implement many mathematical algorithms and, consequently, it became the language of choice for implementing large parts of Mathematica itself. Retrospectively, this was a huge success as it made it possible to implement many more algorithms quickly and cheaply using a more expressive language.
Joule is a front-end GUI app for traders from the market leader of European energy trading. Although most of the lines of code in Joule are C# they chose to implement some parts of it in F#. In particular, the implied prices engine that combines real bids and asks across related contracts to create implicit bids and asks was written entirely in F#. Retrospectively, this was a huge success as it replaced a substantial (~50kLOC) C++ code base with a comparatively tiny (~1kLOC) F# code base that does the same thing more quickly. The author of Joule's implied prices engine wrote a related article here.
Microsoft's Halo 3 computer game and Bing search engine both have some of their dense mathematical code written in Microsoft's own functional language F#.
My professor told us that we could choose a programming language for our next programming assignment. I've been meaning to try out a functional language, so I figured I'd try out clojure. The problem is that I understand the syntax and understand the basic concepts, but I'm having problems getting everything to "click" in my head. Does anyone have any advice? Or am I maybe picking the wrong language to start functional programming with?
It's a little like riding a bike, it just takes practice. Try solving some problems with it, maybe ProjectEuler and eventually it'll click.
Someone mentioned the book "The Little Schemer" and this is a pretty good read. Although it targets Scheme the actual problems will be worth working through.
Good luck!
Well, for me, I encountered the same problem as you do in the beginning when I started doing OCAML, but the trick is that you must start thinking about what you want from the code and not how to do it!!!
For example, to calculate the square of list's elements, forget about the length of the list and such tricks, just think mathematically like that:
if the list is empty -> I am done
if not, then the list must have a head and tail -> you calculate the square of the head, then ask your function to do the same with the tail.
Just think about the general case and the base one, and that you are emitting data and not modifying it (unless you want to modify it ;) ).
Good luck!
You could check out The Little Schemer.
How about this: http://www.defmacro.org/ramblings/lisp.html
It is a very simple, step-by-step introduction to thinking in lisp from the point of view of a regular imperative programmer (Java, C#, etc.).
For educational purposes I would recommend PLT Scheme. It is a portable and powerful environment with very good examples and an even better documentation. It will help you to discover the thoughts behind functional programming step by step and in a very clean way. Choosing a little application to implement will help you learning the new language.
http://www.plt-scheme.org/
Additionally "Structure and Interpretation of Computer Programs" of H. Abelssn, G. Sussman, and J. Sussman is a very good book regarding Scheme (and programming).
Regards
mue
Take a look at 99 Lispy problems
Some thoughts on Lisps, not specific to Clojure (I'm not a Lisp expert, so I hope they're mostly correct and useful):
Coding in AST
I know little about compiler or interpreter theory, but every time I code in Lisp, it amazes me that it feels like directly building an AST.
That's part of what "code = data" means, coding in Lisp is a lot like filling data structures (nested lists) with AST nodes. Amazing, and it's easy to read too (with the right text editor).
A Programmable Programming Language
So code chunks are just nested lists, and list operations are part of the language. So you can very easily write Lisp code that generates Lisp code (see Lisp macros). This makes Lisp a programmable (in itself!) programming language.
This makes building a DSL or an interpreter in Lisp is very easy (see also meta-circular evaluation).
Never reboot anything
And in most Lisp systems, code (including documentation) can be introspected and hot swapped at run time.
Advanced OOP
Then, most Lisp Systems have some sort of Object System derived from CLOS, which is an advanced (compared to many OOP implementations) and configurable Object System (see The Art of the Metaobject Protocol).
All these features where invented long ago, but I'm not sure they are available in many other programming languages (although most are catching up, e.g. with closures), so you have to "rediscover" and get used to these by practicing (see the books in other answers).
Just remember: it's all data!
Write some simple classic functions that Lisp is good at, like
reverse a list
tell if an atom is somewhere in an s-expression
write EQUAL to tell if 2 s-expressions are equal
write FRINGE to get the list of atoms at the fringe of an s-expression
write SUBST, then write SUBLIS
Symbolic differentiation
Algebraic simplification
write a simple EVAL and/or APPLY
Understand that Lisp is good for these kinds of no-side-effect functional programs.
It is also useful for stateful side-effect (non-functional) programs, but those are more like "programs" than "functions".
Which is better for a given application depends on the application. In general, it should contain no less, and no more, state information than necessary.
Easy!
M-x lisp-mode
OK, OK, so you might not have Emacs for a brain. In all seriousness, what you need to do is to get really good at recursion. This can be quite a brain warp initially when trying to extend the concept of recursion beyond the canonical examples, but ultimately it will result in more fluid, lispy code.
Also, a lot of people get hung up on the parenthesis, and I don't really know why - the syntax is very simple and consistent and can be mastered in minutes. For me, I came to Scheme after having learned C++ and Java, and I always thought that the difference between "functions" and "operators" was a false dichotomy, and it was refreshing to see that distinction eliminated.
As far as functional programming goes, as long as you can wrap your head around the fact that a function is a first-class value and can be passed both into and out of other functions you should be fine. The usefulness of this will become clear over time, but it's enough that you can write function-taking and function-returning functions.
Finally, I'm not sure what support Clojure has for macros, but they're considered an essential part of lisp. However, I wouldn't worry about learning them until you're deeply familiar with the above items - though macros are incredibly useful and versatile, they're also used less often than the other techniques I mentioned.
I'd start with a language that can be interpreted. I found Moscow ML to be fairly easy. It is a lightweight implementation of Standard ML.
My personal practice is to find a small project (something that might take 3-5 nights hacking away) and implement it. How about a blog filter tool? Maybe just a Towers of Hanoi or Linked List implementation (those are usually 1-night projects).
The way it usually works out is I implement it poorly the first time, throw away what I had, and it finally clicks a few hours in.
A HUGE help is taking a course in something like... um... LISP! :) The homework will force you to confront a lot of the concepts and it clicked for me long before the semester ended.
Good luck!!
Good luck. It took me until about halfway through the "Programming Languages" course in college before Scheme "clicked". Once that happened, though, everything just made sense, and I fell in love with functional programming.
Write a Lisp interpreter in Lisp.
If you haven't alrady, read up on what makes lisp a unique language. If you don't do this first, you'll be trying to do the same things you could do in some other programming languages.
Then try to implement some small thing (try to make it useful to you or you might not have the motivation).
Lisp in a box is a great way to get your feet wet.
For me the important thing is to make sure you do everything in a 'lisp-y' way. Don't be tempted to think 'In Java I'd use a for loop here, how do I do for loops in Lisp?' but to go through enough examples and tutorials (as someone pointed out, SICP is perfect for this) that you can start to spot when code looks 'Lisp-y' and recognise common language paradigms.
I certainly know the feeling of looking at some code I've just written and intuitively knowing that it's correctly idiomatic for that language and platform/framework - that, I think, is when it 'clicks'.
Edit: And kudos for choosing a functional language, lesser students would have just done it in Java :)
Who said it is going to click? I'm always confused
But if you think about how much abstraction it is possible to hide away, behind lisp macros. Then your brain will explode.
:)
I'd check out Programming Clojure. It's a great book for non-lispers.
In addition to what other SO'ers have already suggested, here are my 2 cents:
Start learning the language and try out a few simple numerical/hobby problems in the language
IMPORTANT: Post the solution/code to StackOverflow, asking for people's opinion if that is really the LISPy way to do it.
Best of luck!
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I really feel that I should learn Lisp and there are plenty of good resources out there to help me do it.
I'm not put off by the complicated syntax, but where in "traditional commercial programming" would I find places it would make sense to use it instead of a procedural language.
Is there a commercial killer-app out there that's been written in Lisp ?
Lisp is a large and complex language with a large and complex runtime to support it. For that reason, Lisp is best suited to large and complicated problems.
Now, a complex problem isn't the same as a complicated one. A complex problem is one with a lot of small details, but which isn't hard. Writing an airline booking system is a complex business, but with enough money and programmers it isn't hard. Get the difference?
A complicated problem is one which is convoluted, one where traditional divide and conquer doesn't work. Controlling a robot, or working with data that isn't tabular (languages, for example), or highly dynamic situations.
Lisp is really well suited to problems where the solution must be expandable; the classic example is the emacs text editor. It is fully programmable, and thus a programming environment in it's own right.
In his famous book PAIP, Norvig says that Lisp is ideal for exploratory programming. That is, programming a solution to a problem that isn't fully understood (as opposed to an on-line booking system). In other words: Complicated problems.
Furthermore, learning Lisp will remind you of something fundamental that has been forgotten: The difference between Von Neumann and Turing. As we know, Turing's model of computation is an interesting theoretical model, but useless as a model for designing computers. Von Neumann, on the other hand, designed a model of how computers and computation were to execute: The Von Neumann model.
Central to the Von Neumann model is that you have but one memory, and store both your code and your data there. Notice carefully that a Java program (or C#, or whatever you like) is a manifestation of the Turing model. You set your program in concrete, once and for all. Then you hope you can deal with all data that gets thrown on it.
Lisp maintains the Von Neuman model; there is no sharp, pre-determined border between code and data. Programming in Lisp opens your mind to the power of the Von Neumann model. Programming in Lisp makes you see old concepts in a new light.
Finally, being interactive, you'll learn to interact with your programs as you develop them (as opposed to compile and run). This also change the way you program, and the way you view programming.
With this intro I can finally offer a reply to your question: Will you find places where it outshines "traditional" languages?
If you are an advanced programmer, you need advanced tools. And there is no tool more advanced than Lisp.
Or, in other words: The answer is yes if your problems are hard. No otherwise.
One of the main uses for Lisp is in Artificial Intelligence. A friend of mine at college took a graduate AI course and for his main project he wrote a "Lights Out" solver in Lisp. Multiple versions of his program utilized slightly different AI routines and testing on 40 or so computers yielded some pretty neat results (I wish it was online somewhere for me to link to, but I don't think it is).
Two semesters ago I used Scheme (a language based on Lisp) to write an interactive program that simulated Abbott and Costello's "Who's on First" routine. Input from the user was matched against some pretty complicated data structures (resembling maps in other languages, but much more flexible) to choose what an appropriate response would be. I also wrote a routine to solve a 3x3 slide puzzle (an algorithm which could easily be extended to larger slide puzzles).
In summary, learning Lisp (or Scheme) may not yield many practical applications beyond AI but it is an extremely valuable learning experience, as many others have stated. Programming in a functional language like Lisp will also help you think recursively (if you've had trouble with recursion in other languages, this could be a great help).
In response to #lassevk:
complicated syntax??
The syntax for lisp is incredibly simple.
Killer app written in lisp: emacs. Lisp will allow you to extend emacs at will to do almost anything you can think of that an editor might do.
But, you should only learn lisp if you want to, and you may never get to use at work ever, but it is still awesome.
Also, I want to add: even if you find places where lisp will make sense, you will probably not convince anyone else that it should be used over java, c++, c#, python, ruby, etc.
I can't answer from first-hand experience but you should read what Paul Graham wrote on Lisp. As for the "killer-app" part, read Beating the averages.
I programmed in Lisp professionally for about a year, and it is definitely worth learning. You will have unparalleled opportunity to remove redundancy from your code, by being able to replace all boilerplate code with functions where possible, and macros where not. You will also be able to access unparalleled flexibility at runtime, translating freely between code and data. Thus, situations where user actions can trigger the need to build complex structures dynamically is where Lisp truly shines. Popular airline flight schedulers are written in Lisp, and there is also a lot of CAD/CAM in Lisp.
Lisp is very useful for creating little DSLs. I've got a copy of Lisp in a Box running at work and I've written little DSLs to interrogate SQL server databases and generate data layers etc in C#. All my boiler plate code is now written in lisp macros that output to C#. I generate HTML, XML, all sorts of things with it. While I wish I could use Lisp for everyday coding, Lisp can bring practical benefits.
If you like programming you should learn Lisp for the pure joy of it. XKCD perfectly expresses the intellectual enlightenment that ensues. Learning Lisp is for the programmer what meditation is for the Buddhist monk (and I meant this without any blasphemous connotation).
Any language looks a lot harder when one doesn't use the common indentation conventions of a language. When one follows them of Lisp, one sees how it expresses a syntax-tree structure quite readily (note, this isn't quite right because the preview lies a little; the r's should align with the fns in the recursive quicksort argument):
(defun quicksort (lis)
(if (null lis)
nil
(let* ((x (car lis))
(r (cdr lis))
(fn (lambda (a)
(< a x))))
(append (quicksort (remove-if-not fn
r))
(list x)
(quicksort (remove-if fn
r))))))
I found that learning a new language, always influences your programming style in languages you already know. For me it always made me think in different ways to solve a problem in my primary language, which is Java. I think in general, it just widens your horizon in term of programming.
I took a "lisp class" in college back in the eighties. Despite grokking all the concepts presented in the class, I was left without any appreciation for what makes lisp great. I'm afraid that a lot of people look at lisp as just another programming language, which is what that course in college did for me so many years ago. If you see someone complaining about lisp syntax (or lack thereof), there's a good chance that they're one of those people who has failed to grasp lisp's greatness. I was one of those people for a very long time.
It wasn't until two decades later, when I rekindled my interest in lisp, that I began to "get" what makes lisp interesting--for me anyway. If you manage to learn lisp without having your mind blown by closures and lisp macros, you've probably missed the point.
Learning LISP/Scheme may not give you any increased application space, but it will help you get a better sense of functional programming, its rules, and its exceptions.
It's worth the time investment just to learn the difference in the beauty of six nested pure functions, and the nightmare of six nested functions with side effects.
From http://www.gigamonkeys.com/book/introduction-why-lisp.html
One of the most commonly repeated
myths about Lisp is that it's "dead."
While it's true that Common Lisp isn't
as widely used as, say, Visual Basic
or Java, it seems strange to describe
a language that continues to be used
for new development and that continues
to attract new users as "dead." Some
recent Lisp success stories include
Paul Graham's Viaweb, which became
Yahoo Store when Yahoo bought his
company; ITA Software's airfare
pricing and shopping system, QPX, used
by the online ticket seller Orbitz and
others; Naughty Dog's game for the
PlayStation 2, Jak and Daxter, which
is largely written in a
domain-specific Lisp dialect Naughty
Dog invented called GOAL, whose
compiler is itself written in Common
Lisp; and the Roomba, the autonomous
robotic vacuum cleaner, whose software
is written in L, a downwardly
compatible subset of Common Lisp.
Perhaps even more telling is the
growth of the Common-Lisp.net Web
site, which hosts open-source Common
Lisp projects, and the number of local
Lisp user groups that have sprung up
in the past couple of years.
If you have to ask yourself if you should learn lisp, you probably don't need to.
Learning lisp will put Javascript in a completely different light! Lisp really forces you to grasp both recursion and the whole "functions as first class objects"-paradigm. See Crockfords excellent article on Scheme vs Javascript. Javascript is perhaps the most important language around today, so understanding it better is immensely useful!
"Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot."
--Eric S. Raymond, "How to Become a Hacker"
http://www.paulgraham.com/avg.html
I agree that Lisp is one of those languages that you may never use in a commercial setting. But even if you don't get to, learning it will definitely expand your understanding of programming as a whole. For example, I learned Prolog in college and while I never used it after, I gave me a greater understanding of many programming concepts and (at times) a greater appreciation for the languages I do use.
But if you are going to learn it...by all means, read On Lisp
Complicated syntax? The beauty of lisp is that it has a ridiculously simple syntax. It's just a list, where each element of the list can be either another list or an elementary data type.
It's worth learning because of the way it enhances your coding ability to think about and use functions as just another data type. This will improve upon the way you code in an imperative and/or object-oriented language because it will allow you to be more mentally flexible with how your code is structured.
Gimp's Script-Fu is lipsish. That's a photoshop-killer app.
Okay, I might be weird but I really don't like Paul Graham's essays that much & on Lisp is a really rough going book if you don't have some grasp of Common Lisp already. Instead, I'd say go for Siebel's Practical Common Lisp. As for "killer-apps", Common Lisp seems to find its place in niche shops, like ITA, so while there isn't an app synonymous with CL the way Rails is for Ruby there are places in industry that use it if you do a little digging.
To add to the other answers:
Because the SICP course (the videos are available here) is awesome: teaches you Lisp and a lot more!
Killer app? Franz Inc. has a long list of success stories, but this list only includes users of AllegroCL... There are probably others. My favourite is the story about Naughty Dog, since I was a big fan of the Crash Bandicoot games.
For learning Common Lisp, I'd recommend Practical Common Lisp. It has a hands-on approach that at least for me made it easier than other books I've looked at.
You could use Clojure today to write tests and scripts on top of the Java VM. While there are other Lisp languages implemented on the JVM, I think Clojure does the best job of integrating with Java.
There are times when the Java language itself gets in the way of writing tests for Java code (including "traditional commercial programming"). (I don't mean that as an indictment of Java -- other languages suffer from the same problem -- but it's a fact. Since the topic, not Java, I won't elaborate. Please feel free to start a new topic if someone wants to discuss it.) Clojure eliminates many of those hindrances.
Lisp can be used anywhere you use traditional programming. It's not that different, it's just more powerful. Writing a web app? you can do it on Lisp, writing a desktop application? you can do it on Lisp, whatever, you can probably do it on Lisp, or Python, or any other generic programming (there are a few languages that are suited for only one task).
The biggest obstacle will probably be acceptance of your boss, your peers or your customers. That's something you will have to work with them. Choosing a pragmatic solution like Clojure that can leverage the current install base of Java infrastructure, from the JVM to the libraries, might help you. Also, if you have a Java program, you may do a plug-in architecture and write Clojure plug-ins for it and end up writing half your code in Clojure.
Not a reason but (trivial) AutoCAD has LISP & DCL runtime support. It is a convenient way to write complex macros (including ActiveX automation) if you don't want to use VBA or their C++ or .NET SDKs, or if a DIESEL expression doesn't cut it.
A lot of AutoCAD's functions are actually LISP routines.
This is a topic i myself have pondered for a while but I have not really come to a decision, as usual time is the main problem... ;)
And since I canĀ“t find these links sofar in this post i add them for public interest:
Success and Failure story:
Lisping at JPL
Really impressive success story:
Lisp in use at the Orbitz corporation
Comparison and analysis of whether to use Lisp instead of Java:
Lisp as an Alternative to Java
Syntax is irrelevant, readability is not!
Not saying this is a killer app but it looks like it could be cool
http://code.google.com/p/plop/
Killer app? The flight search engine by ITA Software is one.
As for "why", it will most probably make you a better developer and is extremnely unlikely to make you a worse one. It may, however, make you prefer lisp dialects to other languages.