
How Python is killing Lisp - pmiller2
http://ynniv.com/blog/2006/11/how-python-is-killing-lisp.html
======
mark_l_watson
I wrote 2 Springer-Verlag Lisp books in ancient times, and have about 25 years
of Lisp experience.

That said, Ruby has mostly replaced Lisp in my toolbox. When I do use a Lisp
family language, it is most often Gambit-C Scheme to build small standalone
executables - and sometimes Franz or SBCL Common Lisp.

BTW, I consider Python and Ruby to be fairly interchangable - use whichever
you like best. Both are great languages with great libraries and supporting
open source projects.

~~~
mahmud
Mark, you're a polyglot. I would say for the last 20 years you have been a
C++, then Java author more than a Lisp programmer.

The first C++ book I ever owned was yours, the one about artificial agents
that had a sculpture on the cover, and that must have been 15 years ago.

If you're in the business of education, your "toolbox" is essentially whatever
people need to learn. You wouldn't hear an English teacher in Korea with 25
years of experience saying she is done teaching English, because teaching
Spanish is so much more easier. That doesn't make any sense. At the time you
wrote the published Lisp books, it was the height of AI-bubble and people
needed to learn Lisp and Prolog. Then you wrote an Smalltalk book (IIRC.) then
C++, Java .. all dictated by what the public needed.

Btw, you still have the literary and expository prowess to teach today's hot
technologies as well. But that doesn't say anything about Lisp, Prolog,
Smalltalk, C++, or Java except that you are no longer in the business of
teaching them.

And I mightly thank you for the Agents book, btw. I didn't know what I was
doing and just typed in the code into Borland C++ 4.5. The diskette was
missing when I bought it, and I am sure I tried to download the source code
from the Addison-Wesley ftp site (it could have been a Prentice Hall book as
well)

Cheers!

~~~
mark_l_watson
I must admit that I usually think that whatever projects that I happen to be
working on are: most fun, most interesting, etc. Same comment applies to
programming languages, tools, and frameworks. This is a reflection of a simple
fact of life: whatever we think hard about and generally mull over, becomes
very interesting.

------
mnemonicsloth
Three years old.

When this was written, there was no such thing as Clojure [1], and a number of
now-essential CL libraries were just getting started.

Providing no new information, this article just invites needless soapboxing.

[1] Clojure is fast, free, trendy, inherently parallel, and fits seamlessly
into the Java ecosystem. It's just an anecdote, but I notice less complaining
about parentheses, too.

~~~
cema
You are correct. Still I think it offers useful historical perspective.

~~~
mnemonicsloth
Lisp already has too much historical perspective. That's one of the things
people like about Clojure.

------
Scriptor
Personally, it's the double learning curve of having to learn Lisp and Emacs.
I understand the basic concepts of Lisp now, but could someone point me to a
good introduction to learning Emacs, Slime, and Lisp all at once? Does
Practical Common Lisp do that as well?

~~~
enum
You don't have to learn Emacs. Also, Common Lisp isn't the only option. Try
Scheme, this one: www.drscheme.org.

~~~
Scriptor
The thing with Emacs is that I feel like I am missing out on the full
potential of developing in CL if I'm not using it. How true is that?

~~~
gruseom
I don't think it has to be true, though they do go together well. Not all CL
hackers use Emacs. You might consider trying the Lispworks IDE, or the Allegro
IDE (on Windows) or the Clozure IDE (on Mac).

------
m0th87
As a non-lisp programmer, what scares me away is the syntax. I don't think I
could ever wrap my head around the (admittedly succinct) examples I see
online, because it takes so much effort for me to figure out what's going on
in even a few lines of code. Comparatively, I was able to understand what was
going on in most python scripts before I knew the language. Is this something
that just takes a while to get down? Or are some people just naturally prone
to the syntax?

~~~
PieSquared
The reason this syntax scares you is simple: it's different.

At the very root, Python syntax is nearly identical to Java, C, etc.

The syntax of Haskell, OCaml, etc, is a deviation from that of Python, Java,
etc, but not an incredibly significant one. Perhaps you may find that the
syntax of these languages scares you but you think you could probably learn it
after a bit of mind-wrangling.

Lisp, on the other hand, is old. It was developed over 10 years before even C
came to being! So the syntax is completely different, and requires you to
actually learn it instead of just assuming that your knowledge of other
programming languages will pull you through.

In summary, it's not a fault in you. It's just that you are used to C-derived
and influenced syntaxes, but not to Lisp; and the syntax of Lisp is different
enough that you need to actually _learn_ it.

Here's a crash course:

    
    
      (f a b c) is the same as f(a,b,c).
      '(a b c) is kind of like ["a", "b", "c"].
      '(1 2 3) is just like [1,2,3]
      (defun x (a b c ...) ...) defines a function x(a,b,c).
      (+ 1 2 3) is just like +(1,2,3) = 1 + 2 + 3
      (setf x 5) is just like x = 5
      '(a b ,c) is just like ["a", "b", c]
      if L is equal to '(1 2 3), then
        `(10 20 ,@L) is like [10, 20, 1, 2, 3]
    

Now, to be honest, I just showed you nearly 100% of the 'syntax' Lisp has. The
rest is already understanding the language (knowing how to def. functions, how
to do loops, etc).

By the way, what you might find interesting is that I once showed this to a
friend of mine who knew nothing about programming. I showed him how to write a
basic program in Java (with a few subroutines and a loop), then how to do it
in Lisp. He exclaimed, "Argh! If I can do it like this, then why do I need all
those fancy weird words like public and void and what not and braces and...
eugh!"

Sorry for that longish post, I hope you found it at least a bit informative.
;)

~~~
m0th87
Very useful! I suppose I was wrong to say the syntax is confusing, because
lisp is so syntactically minimalistic. But when I look through lisp code, I
can't determine anything with respect to scope. Take, for example, the code in
pg's A Plan for Spam: <http://www.paulgraham.com/spam.html>

(let ((prod (apply #'* probs))) (/ prod (+ prod (apply #'* (mapcar #'(lambda
(x) (- 1 x)) probs)))))

It took me several minutes to weed through this code. Part of that is because
I didn't know what, say, apply did, and had to look it up. That's not an issue
because you have to do that when learning any new language. But I had to
carefully inspect the source bottom-up and break it apart because I couldn't
tell what the arguments are on each function call. An IDE that does block
highlighting would help a lot, but even then it feels overwhelming, because it
only helps me inspect the block that my mouse cursor is currently on.

I guess what I'm saying is, I feel as if the syntactical constructs in other
languages are necessary for me to be able to quickly parse a language.

~~~
mahmud
Paul Graham has a peculiar Lisp style which is NOT mainstream. He is succinct,
clever, and usually performance-agnostic. He writes expository code like we
write one-liners in the repl to quickly test something out.

That example you linked to is confusing because: 1) You don't know the syntax
to read it out like a formula, and 2) he uses the names _prod_ and _probs_
which look the same and strain the mind of a newbie.

The way you read "hard" Lisp code, specially one in Graham's style is to read
from the last line upwards. The tell-tale is the deep indentation, btw.

Start at the last line, which is the body of MAPCAR, you know mapcar is MAP
which applies its first argument function to successive elements of its
second-argument, which should be a list.

    
    
      (mapcar #'(lambda (x) 
                   (- 1 x)) probs)
    

Make a mental note about the free variable, _probs_. You can recognize the
function as the usual arithmetic step of converting integers to probability
values between 0 and 1. The sharp-quote, #', is an archaic style and
unnecessary, so let's wrap up these two lines into a function and change the
names to be readable.

    
    
      (defun normalize-probabilities (probabilities)
        (mapcar (lambda (x)
                  (- 1 x))  probabilities))
    

Ok.

Look up further and notice the result of this function call, a list, is being
reduced to an integer. APPLY applies its first argument, a function, to its
second argument, a list. For example, (apply #'+ (list 1 2 3 4)) means sum of
the first four digits. C programmers should find this familiar: (apply #'main
argv)

Where MAPCAR returns a list, apply returns whatever its function argument is
supposed to return. We know the function #'* takes a list of numbers and
returns their product. So, the snippet is just multiplying the list of
probabilities, or reducing to a scalar.

    
    
      (apply #'* (normalize-probabilities probs))
    

Then:

    
    
      (+ prod (apply #'* (normalize-probabilities probs)))
    

And here something called _prod_ is being added to our scalar. Hmmm.

Look up a bit and see where that's coming from. The nearest binding form for
_prod_ is in the LET body on top. Looks very similar to something we have seen
before. Another application of multiplication to the list named _probs_. This
is not a Lisp issue, it's a Bayesian statistics or perhaps a PG issues. You
continue reading the paper and discover his formula in English prose. Aha! :-)

You can move code around, tuck it into functions and do whatever you want with
it. See if you recognize the code snippet now:

    
    
      (defun normalize-probabilities (probabilities)
        (mapcar (lambda (x)
      	    (- 1 x))  probabilities))
    
      (defun pg-foo-fomula (product)
        (/ product (+ product
      		(apply #'* (normalize-probabilities probs)))))
    
      (defun main ()
        (loop
         (let ((probabilities (eval (read))))
           (when (listp probabilities)
    	     (print (pg-foo-formula (apply #'* probabilities))))
           (princ "OK > "))))
    
    

Typically you don't do that; you don't make silly repls and you never ever
write a MAIN or any other program entry function. You write libraries, that
you use in other libraries, and you orchestrate them all via interactive use
and deploy in a custom image.

~~~
m0th87
You should write a book on practical lisp. I'd buy it!

------
whyenot
Python also wins because it's a living language, still changing, adapting and
updating itself while Common Lisp died the day the ANSI standard was published
and today is a zombie, even if it still smells fairly nice.

Now that comp.lang.lisp is utter crap, there isn't much of a community either
except for #lisp, which as an outsider I find kind of intimidating and not a
good place to ask for help. Actually, what lisp really needs is for Conrad
Barski to clone himself 10x :)

~~~
cema
Well, there is always Clojure, as another commenter mentioned. Its community
is different (friendly and helpful) and so is the language (vibrant, modern
and evolving).

------
kristianp
I started learning scheme recently, and enjoyed it for a while, then went back
to ruby. (I have been programming in Ruby for a few years now.)

If I want to prototype something quickly, I will use ruby. I think the modular
way you can program in an oo language is another factor. It is easy to write a
demo, and then add the class to a rails project. I tried to read about using
modules, such as those used by gambit-c, but the mailing list replies were
dense with jargon, which I found more of a barrier than the parentheses.

I found the scheme environment too fragmented and lacked a decent equivalent
of rubygems. The lack of a non-emacs editor with nice indenting was a
contributing influence.

Replace ruby with python and scheme with lisp above, to see the relevance.

------
alecco
But ECMAScript is killing Python. The writing is on the wall.

~~~
alecco
Hello, (former) fellow python fans. ECMAScript, formerly known as JavaScript,
is doing very well. So well Python developers started to show their concern
for about 2 years. You could read it on PyPy blog and Python mailing lists.

The new ECMAScript VMs are getting faster and already beating Python's. And
they are getting faster with plenty of room to improve. The language is
cleaning up, with a major milestone reached a few days ago. They have the
biggest installed base in the world and there are more developers. The
language fits in precisely the same slot as Python.

The writing _is_ on the wall. Down-voting what you don't like doesn't make it
go away and it should be very un-HN.

EDIT: Read again the name of the story title if you think _my_ post was flame-
bait.

~~~
viraptor
Well - this comment is quite interesting. The parent one looks like a one-line
"meh" comment. I'm quite happy to downvote the original and upvote this one...

But is it really killing python? The language is basically the same (almost-
dictionary based, easily extensible types / prototypes, etc.). There's a big
difference though: afaik there's no real library for ecmascript that would
integrate it with the os. There's simply no way to use ecmascript standalone
on a typical system. ecmascript is good in places where you need an embedded
scripting language, but lua is not enough. Unfortunately neither of them is
useful as a general-purpose language right now. Once someone produces a
serious repl-like environment and a set of sys / os / file libraries - it can
compete with python.

~~~
cema
I agree with the library argument and the GPL argument. And I agree that it is
unfortunate these two languages (Lua and ECMAScript) do not have a complete
standalone environment at this point.

I disagree with the downmod argument: the one-liner did not feel as a "meh"
argument but a succinct reference to an easily (re)constructed (but more
verbose) argument regarding ECMASCript versus Python similar to the original
argument of Python versus Lisp. I think such succinct arguments are fine here
(in fact, I have upmodded it to compensate for what I considered the
undeserved negative score).

~~~
silentbicycle
In what sense does Lua not have a standalone environment? That's news to me.

    
    
       $ lua
       Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
       >

~~~
kzh
Same for javascript... I use the js console all the time. Thank you,
spidermonkey.

