Is Lisp still useful in today's world? (2011)
programmers.stackexchange.com
programmers.stackexchange.com
Learning Lisp just seems to promote better ways of tackling programming problems that is transferable to other languages where it's not as encouraged naturally even if superior.
For example it is my opinion that this function is in no ways inferior to a recursive equivalent:
(defun range (end &key (start 0) (step 1))
(loop for i from start to end by step
collect i))But keep in mind that some things, although recursively defined, are better computed in other ways, the most obvious example is a Fibonacci sequence, which if I really needed, I would precompute and stick in an array for constant time access or something like that(maybe memoize a recursive function).
(defun search (tree val)
(cond
((null tree) nil)
((= (car tree) val) tree)
((< (car tree) val) (search (cadr tree) val))
((> (car tree) val) (search (cddr tree) val))
)
)
I write this sort of code all the time for more complicated structures; iterative solutions would involve keeping track of a bunch of local variables, which only makes the code more difficult to deal with.http://www.amazon.com/Little-Schemer-Daniel-P-Friedman/dp/02...
That's how I write Lisp too. It seems to me the nicest way to minimize overall complexity.
However, whether or not your example shows something that is not inferior is likely a matter of opinion, not fact.
I hadn't written a line of lisp (although counted many brackets when trying to read along) but just studying it helped me think about programming problems a bit differently.
-- Eric S. Raymond
There's a reason Java won't go away and that's that it runs everywhere releatively easily and interfaces with stuff acceptably well.
Python is now doing a good job of this too.
Lisp has a looong way to go on this front and I do speak from some limited experience.
It's very pleasant if all you're doing is staying inside lisp and interacting only with your own code but as soon as it's asked to play nice with others it gets a lot less fun.
And staying inwardly focused, never looking out and never talking to anyone else ultimately means get very little real productive work done.
:(
Clojure runs on the JVM and has great Java interop, so you get the fun of lisp, and the convenience of all the Java libs.
I still personally find JVM languages slow memory hogs during development but that's another issue :P
It's definitely a good offering
Lisp is great if you need a compiler tomorrow. If you have the time, though, I think that other languages are better when there's more time to invest.
EDIT: To actually answer the question, of course it's still relevant and useful, but perhaps other languages have caught up. It's still used in industry (Google uses it via ITA, IIRC).
The other big use of multimethods is when you have static-type function overloading (as in Java/C++) and decide you need to move the overload selection into runtime via the dynamic type of the arguments. This isn't possible in the general case without doing all the dispatch work yourself, but it's a trivial with multimethods.
Is there a clear winner for GUI in Python? GTK, Qt, etc. Python also has quite a few networking libraries; networking in today's world is more than mere sockets.
"SBCL seems to be the de-facto FOSS implantation"
Meh, GNU Clisp is pretty relevant, and a lot of people are using Clozure. CMUCL also remains relevant, if only because of its useful extensions (SBCL is a fork, and dropped many extensions like Motif support).
I think what CL really needs is an update, a CLtL3 that adds support for modern features. Modern Lisps like Clojure and Racket do not have many of the constructs that make CL great (which is not to say that Clojure or Racket are not great languages, but they are missing some of the nicer CL features).
Where-as in the lisp world stuff like the socket interface is DIFFERENT depending on the implementation. So you don't get to pick and choose.
Any examples? Just curious.
1. LOOP -- (loop for i in some-list maximizing i) is just the beginning of nice iterative constructs in CL.
2. Conditions -- continuations are a building block for this, but it's nice to not have to build it up yourself. Agents in Clojure are pretty good also, but not applicable for any exception (correct me if I am wrong, I am not as much of an expert in Clojure as in CL).
Again, just a matter of taste. Clojure and Racket certainly have advantages over CL, just by virtue of supporting more modern features (especially Clojure, which inherits all the features of the Java standard library).
AAAAAND macros too, I guess. They are nice.
</smuglispweeniecomment>
Maybe I'm just too small-time for it to matter but what, exactly, does this commercial support actually buy you? In the last 10 years of programming, I've only run into a handful of bugs in my tools. When dealing with OSS projects, they were already known and fixed in newer versions. When dealing with $BIG_DATABASE_COMPANY they told me to use a workaround and didn't fix the bug until the next major release of the software.
I don't have a problem paying for commercial software, I understand it supports development and improvement of the tools, but what exactly are you getting when you spend (tens or hundreds) of thousands of dollars on licencing costs for support?
But that's pretty rare, IME/O.
On the other hand, isn't one lesson from modern computing that treating data as code is really dangerous? I have yet to see this addressed by Lisp advocates.
Allowing code to be treated as data is a very powerful thing when it comes to programming. But of course, with more power there is more danger.
Maintainability? If done right "code is data" could improve the maintainability, or decrease it drastically, just like any other feature. If you have 80 lines of comments for every 10 lines of code, you've decreased your maintainability, comments are dangerous by that logic.
Maybe the power of Lisp's data-as-code is worth the risk. We don't stop using string concatenation because of SQL injection. It's just that I've never even read so much as a warning about this feature, and I'm curious what Lisp users have to say about it.
eval("dangerous python code here")
As I pointed out, it is a problem in any language that has eval. The way you deal with it, is you never eval anything untrusted, which is actually extremely easy to do. I don't believe I've ever used eval ever.In CL specifically, because the reader can evaluate code as well, every time you use the read function, you should know these two things: 1) never use it for user input. 2) bind read-eval to nil. You'll be fine, or more accurately, no worse than anybody else :)
On the other hand macros, and having a json style serialization format that is much more powerful and actually extensible is a big plus :)
(defun read-data ()
(let ((data (let ((*read-eval* 'nil)) (read))))
(mapcar
(lambda (x) (format 't "~a: ~a~%" (car x) (cdr x)))
data)))
Then I can (read-data)
(("a" . 1) ("b" . 2) ("c" . (funcall (lambda () (princ "I ran code!")))))
And the following will print. a: 1
b: 2
c: (FUNCALL (LAMBDA () (PRINC I ran code!)))
But of course unless I eval the code, arbitrary code will not run (assuming I haven't forgotten some aspect of the reader)....have you really looked? Here is a warning, in the section titled, "Reader Security:"
To be fair, no. I'm not a practicing Lisp programmer; I just admire the language. But I've read a fair number of Lisp tutorials, as well as SICP, and I don't recall it being mentioned. I'm glad it's out there somewhere!
The power of "code is/as data" means that Lisp macros can manipulate code as easily as other Lisp code manipulates data. It's not really about eval.
That seems to be the consensus among all the people replying to me. :-) Fair enough. The difference I see is that lots of Lisp authors praise "no syntax" and code-as-data, so it seems to be encouraged, whereas I don't see Python programmers encouraging use of eval. Lisp seems designed for this kind of meta-programming. And it's really cool! It just makes me nervous.
As an outsider, I really appreciate the responses from you all. Basically you seem to be saying, "It's not an issue. We use it for macros, not for untrusted inputs. Don't call eval and you're fine." Obviously I wouldn't want you to do anything else. :-)
Anyway, thanks for the replies. It's great to have a community where I can ask Lisp users about something like this and learn what they think! It's something I've wondered about for a long time.
1. Python, Perl, Ruby, and even Java have support for code as data. If this makes Lisp a risky language, then you should be very worried about all of the above.
2. It is easier to disable code-as-data primitives (eval for example) than it is to add them to a language that lacks such support. I use Lisp for code that is not public-facing; the ability to extend the program at runtime can be very useful when security is not an issue. Languages that lack support for such things are harder to work with for cases like mine.
3. Code-as-data in Lisp is primarily a compile time feature, not a run time feature. Most Lisp programmers are using this feature via the macro system, rather than having programs that compute new functionality based on their inputs. You can disable all runtime support for treating code as data, and still take advantage of it at compile time.
Ultimately it will help you be a better programmer even if you don't at first see the benefit.
So there are 20,000+ red-black binary tree implementations in Scheme. Great?
Actually there is a theme that a language can be interpretive and, really, still fast enough if mostly it is used just as thin glue to connect other, efficient software where nearly all the time goes. E.g., IBM's in-house mainframes on their VNET were long run heavily with just their interpretive language Rexx: VNET was a little like the Internet except the network was less smart and the computers also played the role of routers. At one time IBM had 3600 such mainframes around the world. I've been using Rexx on Windows as a scripting language and want to convert to PowerShell due to the better access to Windows services.
As a systems programming language I think that lisp has utterly failed. The Lisp machines are dead for various reasons (which I'm researching right now as a side-project) and to the best of my knowledge compiled lisp has clearly not taken the place of C in building operating systems (although I hope to do exactly that as does the author of [http://www.loper-os.org/]).
All of this comes down to an individual's definition of utility. Lisp is by definition of Turing Completeness just as capable as any other language you may wish to name, but with the usual Turing Tarpit or small language warning that you may have to roll your own. My perception, and one which several posts here on HN has affirmed is that traditionally Lisp was used by lone AI researchers who needed the power to roll their own anything quickly and efficiently. As a result of this "roll my own" mentality and simple lack of the internet (it was early and mid 1980s or so) libraries and SDKs as we know them were never built for Lisp systems.
Another difficulty is that as several other comments note there is no "one true" standard for Lisp. There is Scheme (which has official specs), there is ANSI Common Lisp which is a spec upon which several implementations have been based, and then there are countless other DIY and nonstandard lisps which elect to use different function names and otherwise make code non-trivially portable between lisp implementations. Not having a clear standard didn't help the lack of a library ecosystem at all, but some dialects such as Common Lisp and Clojure seem to be developing workable community library ecosystems. Of late Common Lisp has grown a library structure via ASDF code loading tool and the Quicklisp package manager, but Clojure is the only lisp I've ever encountered that really made any effort at all in the direction of providing native support for packaged libraries. The Clojure language includes syntax designed for allowing one file to explicitly state and "require" code in other files or even other libraries: a feature which is lacking from the Common Lisp standard. Thanks to technomancy's Leiningen tool and the clojars repository Clojure has a user-created system similar to Quicklisp + ASDF but trading ASDF's search path idiosyncrasies for a search path structure which should be familiar (or at least unsurprising) to Java developers.
TL;DR / Conclusion
If your boss comes to you and asks you to write a webpage, Lisp is probably not what you turn to. Could you? Sure, <shamelessplug> my blog is built in Clojure [http://arrdem.com].</shamelessplug> [http://refheap.com] is built in Clojure. [http://www.chris-granger.com/] is (presumably) Clojure. I know I've seen blogs in Common Lisp and other dialects but URLs escape me. Your boss says "Access the database", there are Clojure (okay fine Java but there is no real difference) libraries for SQL, MongoDB, Cassandra and more. Common Lisp also has SQL and MongoDB libraries. In short, while there is value in Lisp it is (for the time) not practically greater than the value of any other language despite the elegance of the functional approach and the power of the macro system. Hence its failure thus far to take over the world. However that same value proposition is improving as the CL and Clojure communities create and publish ever more libraries leading me to hope that Lisp may indeed take over the world one day.
Another point is that this site is the proof of an approach to software development described in the On Lisp book. So, it is not a gratification, it is just a real-world project they have done for themselves to make money. It is not some showcase or a demo, it is real thing.
In case of Django, I think, it will require much more man-hours for building and maintaining and more resources (cost) to run.
This is an example of Less is More principle in action: less code (the core language concept) and, as a consequence, less everything - time, people, money.
Lisp isn't just a language with parenthesis. It is a whole philosophy (a multi-paradigm language). Well, better to read On Lisp.