
Python for Lisp Programmers (2000) - bshanks
http://norvig.com/python-lisp.html
======
rauhl
This seems to be a good excuse to share this great story:

> At ILC 2002 former Lisp giant now Python advocate Peter Norvig was for some
> reason allowed to give the keynote address like Martin Luther leading Easter
> Sunday mass at the Vatican and pitching Protestantism because in his talk
> Peter bravely repeated his claim that Python is a Lisp.

> When he finished Peter took questions and to my surprise called first on the
> rumpled old guy who had wandered in just before the talk began and eased
> himself into a chair just across the aisle from me and a few rows up.

> This guy had wild white hair and a scraggly white beard and looked
> hopelessly lost as if he had gotten separated from the tour group and
> wandered in mostly to rest his feet and just a little to see what we were
> all up to. My first thought was that he would be terribly disappointed by
> our bizarre topic and my second thought was that he would be about the right
> age, Stanford is just down the road, I think he is still at Stanford — could
> it be?

> ‘Yes, John?’ Peter said.

> I won’t pretend to remember Lisp inventor John McCarthy's exact words which
> is odd because there were only about ten but he simply asked if Python could
> gracefully manipulate Python code as data.

> ‘No, John, it can’t,’ said Peter and nothing more, graciously assenting to
> the professor’s critique, and McCarthy said no more though Peter waited a
> moment to see if he would and in the silence a thousand words were said.

from [http://smuglispweeny.blogspot.com/2008/02/ooh-ooh-my-turn-
wh...](http://smuglispweeny.blogspot.com/2008/02/ooh-ooh-my-turn-why-
lisp.html)

~~~
kennytilton
Strange that six years into my Lisp-hood I could not recognize the great one.
Or the great beard: [https://www.independent.co.uk/news/obituaries/john-
mccarthy-...](https://www.independent.co.uk/news/obituaries/john-mccarthy-
computer-scientist-known-as-the-father-of-ai-6255307.html) It never changed!

~~~
flavio81
>Strange that six years into my Lisp-hood I could not recognize the great one.

God disguises in mysterious ways...

RIP John McCarthy

------
norvig
Some points:

\- Yes, the original publication year was 2000. I've added that to the file.

\- @HelloNurse: You've got the key point. I provided Lisp code to teach AI;
but my goal was to teach AI, not Lisp. As more schools and students were
familiar with Python and not with Lisp, I needed to make the switch to keep
teaching AI effectively.

\- @jonathanstrange: Yes, "batteries included" is key to Python; there is some
pain in doing any change; this page attempted to alleviate some of the pain.

\- @rauhl: "in the silence a thousand words were said". I'm not sure what
words are in that silence. But to me, the words are: Lisp and Python are
different ecosystems with different customs. The Lisp community likes to solve
lots of problems with macros. The Python community doesn't. For 95% of the
usages, neither approach is better than the other, they are just different.
For example, in Python, `with` is a statement, and you define custom classes
for each usage you think of. In Lisp, you define a macro like `with-open-file`
for each usage. The end result in usability and efficiency is similar. In
Lisp, you often define macros for custom data types, e.g.

    
    
        (def-tree T1
            root (A B C)
            A (D E)
            B (E F)
            ...)
    

In Python you use a combination of built-in data types (like dicts), custom
classes, and ad-hoc parsers of text. Again, the approach is different, but
readability and efficiency is similar.

It is certainly true that if you want to define, say, a mock Prolog system, it
is easier to do it in Lisp with macros than in Python, where you would need to
deal with the far messier `ast.parse` module. Is that where the silent words
were? For me the words would be "Lisp is a much better choice if your primary
goal is defining a full-blown domain specific language. For most other
programming tasks, the two languages offer similar functionality in different
way."

~~~
flavio81
_> The Lisp community likes to solve lots of problems with macros. The Python
community doesn't. For 95% of the usages, neither approach is better than the
other, they are just different_

I'd like to interject for a moment.

As a software engineer with some years of using Python for financial software,
and afterwards switching to Common Lisp, i diverge. In my opinion, Lisp macros
make all the difference in the world, and I really miss them when using a
language that doesn't support them. Sure, anything can be implemented on most
languages including Python, but there is a big difference in the
maintainability and clearness of the resulting code, as well as in effort.

So, are you abandoning us, Peter? If not nil, i will signal 'tears and no
handler-bind will recover me from this condition. (joking of course)

Anyways, thanks for PAIP, it will always be in my heart.

 _(Note for the uninitiated: PAIP stands for "Paradigms of Artificial
Intelligence: Case Studies in Common Unpython", a classic book by Peter Norvig
who is part of the big PPP of Lisp literature: Paul (Graham), Peter (Norvig),
and Peter (Seibel))_

~~~
kennytilton
"The Lisp community likes to solve lots of problems with macros" sounds like
"Mozart likes to use a lot of notes". I do not like to use macros, I like to
hide boilerplate so the semantics stand out. And so I can type less. I do not
like typing. But Siri can stuff it. I digress.

------
icc97
It's worth noting that one of the main pain points mention of Python was that
it was 2-100 times slower (vs 1-2x slower for Lisp). The slowest elements of
Python compared to C++ were matrix multiplication (278x slower), array access
(141x slower) and heapsort (84x slower). NumPy solves the two slowest,
although I can't find an obvious contender for the sorting.

~~~
masklinn
> heapsort (84x slower) […] I can't find an obvious contender for the sorting.

Use the built-in sort instead of hand-rolling your own? The built-in sort is
not a heapsort and though I don't know what it was before the 2.3 "timsort"
implementation, the essay mentions Python 2.7 so I would assume it's not
talking about the old built-in sort either.

~~~
hellofunk
This article predates Python 2.7 by 10 years.

The link to 2.7 was probably added or edited many years later.

------
dwarfylenain
And what about hylang.org ? I'm surprised it's not even mentioned here : nice
lispy syntax with all the python packages = best of both worlds :)

~~~
pieterr
The Norvig’ article is from 2000. (Hy is from 2013.)

------
susam
I like how code in both Python and Lisp can often look similar despite
different syntaxes, different conventions, and different philosophies.

Here is a toy example of file I/O in Python 3:

    
    
      with open('foo.txt', 'w') as f:
          print('hello, world', file=f)
    
      with open('foo.txt') as f:
          print(f.readline())
    

Here is a similar example in Common Lisp:

    
    
      (with-open-file (f "foo.txt" :direction :output :if-exists :supersede)
        (format f "hello, world~%"))
    
      (with-open-file (f "foo.txt")
        (format t "~a~%" (read-line f)))
    

This example is a bit contrived to show the similarities. Real and idiomatic
code may not look so strikingly similar. But similarities in concepts,
constructs, and structure of code emerge in both languages. In fact the
article mentions, "Take a Lisp program, indent it properly, and delete the
opening parens at the start of lines and their matching close parens, and you
end up with something that looks rather like a Python program."

~~~
lmm
Are they really any more similar to each other than to any other random
language? E.g. Java:

    
    
        try(Writer f = new PrintWriter("foo.txt")) {
          f.println("hello, world");
        }
    
        try(BufferedReader f = new BufferedReader(new FileReader("foo.txt"))) {
          println(f.readLine());
        }

~~~
xyrouter
Do other popular languages support a similar construct? C? C++? Perl?

The Java try-with-resources was introduced in Java 7 (2011).

The Python with statement was introduced in Python 2.5 (2006).

The Lisp with-open-file has been in Common Lisp Hyperspec for a long time
(1960s?).

Not that it takes anything away from Java. I think all languages are gradually
converging to the features of Lisp.

~~~
lmm
> Do other popular languages support a similar construct? C? C++? Perl?

C? No, though I don't really think of that as an actively maintained language.
C++ and Perl achieve the same thing via RAII.

> Not that it takes anything away from Java. I think all languages are
> gradually trying to or discovering the approach the features and
> expressiveness of Lisp.

I think language design converges over time, alternating between expressive-
but-unmaintainable and structured-but-too-strict but getting closer to the
ideal as we advance. In many ways Lisp isn't a complete language design at all
- rather macros are there for the user to finish the language themselves.

~~~
sedachv
> C? No, though I don't really think of that as an actively maintained
> language.

Why would you think that? Work on the C standard is ongoing: [http://www.open-
std.org/jtc1/sc22/wg14/](http://www.open-std.org/jtc1/sc22/wg14/)

~~~
lmm
Just that I hadn't heard of a new release since 1999, shrug.

------
kennytilton
Methinks the enumeration of "Lisp's essential features" a tad short. 1. Coding
JS quite a bit these days, I greatly miss every form returning a value. 2.
Python's lambda is just sad, and GvR keeps threatening to remove even that.
And people, please, once and for all, 3. those parentheses and where we put
the operator are absolutely essential to the Lisp experience.

~~~
fulafel
Re 2 - are you bothered by the fact that there is this thing that Python calls
lambda, and it would be fine if it was called exprfn or something? Or do you
think there is really a big problem with using def in the would-be-lambda's
scope to give a temporary name for the function?

~~~
kennytilton
Python's lambda was pretty sad last I looked. Has it caught up with
Lisp/Clojure's? And has the BDFL stopped trying to eliminate it altogether? I
heard he regretted adding it and wanted to yank it at some point. The D in
BDFL looks a lot bigger than the B.

~~~
fulafel
Python's lambda is unchanged, and it is still included.

I have the impression that Guido regrets adding it because of the language-
design-aesthetic wart - the recurring "why is it called lambda when it can
only define single-expression functions?" "you can just use def in the scope
just before use, if you need statements" "but then it's not anonymous!" "just
use a temp name" dialog loop.

~~~
kennytilton
You know, I completely misapprehended your original query. No, it is fine that
GvR called it "lambda". Had he called it experfn we would all translate
mentally to "lambda" anyway. I am just sorry Mr. Norvig considers it
equivalent to Lisp's, or does not consider it essential to Lispy-ness.

~~~
kazinator
The situation is worse: Python doesn't support _let_. It's so bad that the Hy
people aren't able to support _let_ in their Lisp-skin-over-Python.

Python's handling of local variables, whereby assignment and binding are
conflated, is perpetrating a harm to the education of neophytes.

It also means that "x = 42" can never be an "assignment to undefined variable
x" error in Python, even when in fact it is that error: the programmer thinks
there is an existing x being modified, but there isn't. Or more likely, the
programmer thinks that an existing y is being modified which _does_ exist, but
made a typo and wrote x instead.

------
kbp
One distinction between Lisp and Python's docstrings that he didn't mention is
that in Lisp, you can (and it's normal to) give docstrings to variables; you
can then look these up later with DOCUMENTATION or however else you read
docstrings:

    
    
        CL-USER> (documentation '*print-readably* 'variable)
        "If true, all objects will be printed readably. If readable printing
          is impossible, an error will be signalled. This overrides the value of
          *PRINT-ESCAPE*."
        CL-USER> (documentation '+ 'variable)
        "the value of the most recent top level READ"
        CL-USER> (defvar *variable* nil "a variable")
        *VARIABLE*
        CL-USER> (documentation '*variable* 'variable)
        "a variable"

------
didibus
I wish all languages were Lisps. Code as data, partial functions, higher order
functions, everything is an expression, and recursive evaluation. That's the
basis, and I wish more languages had a similar foundation.

Now, the article details Python sharing a lot of features with Common Lisp,
often just called Lisp. Which is true, but the foundation is very different.

------
a_c
Would appreciate if the reverse (Lisp for python programmer) exists.

~~~
icc97
Second sentence:

> Although it wasn't my intent, Python programers have told me this page has
> helped them learn Lisp

~~~
a_c
obviously the lazy me didnt click through the article. thanks!

~~~
nerpderp83
Mentioned elsewhere in the thread but take a look at Hy Lang, a lisp that
compiles down to Python.

------
madmax96
I was reading the Lisp code and thinking "why wouldn't this evaluate to (S)?"
And, of course, it does.

The invocation of the lisp program should be:

    
    
        (generate 'sentence)

------
jonathanstrange
Okay, I certainly don't want to start a language war, so let me be kind. There
is one legitimate reason to switch from Lisp to Python: The number of packages
and extensions. Python really has more than just batteries included, it's
probably the language with the most available libraries after C++.

Still, switching from Lisp to Python is bound to be painful...

~~~
sametmax
Some other reasons:

\- you use softwares that are scriptable in Python (SIG, Blender, etc)

\- you write a lot of glue code. That pretty much Python raison de vivre.

\- you do a lot of data analysis manually. Pandas is the new excel, and
jupyter the new matlab.

\- you do a lot of sysadmin. Scripting is just easier in a dynamic language.

\- you do a lot of CRUD websites. You just can't beat the frameworks from this
language for this kind of things. They do most of the work for you, and do
security better than you do.

\- you want to integrate new members in your team faster. Python is easier to
learn than lisp.

\- you are coding a GUI. With kivy you can target desktop and mobile with one
code base, and some skins are pretty
([https://imgur.com/a/IjM0XGW](https://imgur.com/a/IjM0XGW)). With QT you can
do powerful things on the desktop. With wx you can do simple GUI simply.

\- you have a lot of different kinds of task at hand, and don't want to have
too many different languages in your stack. Python is never the best language
at anything, but it's a damn good language for most things, so it makes it a
versatile toolbox.

~~~
pimeys
One thing I don't understand here why somebody needs to switch to Python and
forget other languages? Sometimes I too hack something fast with Python, but
still write lots of Rust and Clojure. Then if I need Python, it is very easy
to just write some and get things done.

~~~
msl09
What I don't understand is the necessity of having the video of the naked
pirates of the caribbean guy in the corner.

~~~
sametmax
That's a picture for my blog (well actually the related twitter account),
which essentially deals with Python and porn. I was not going to make a new
screen capture just for HN.

------
mattlondon
Obligatory: "Dude, where's my car?"

------
pieterr
Since the Japanese translation was done in 2002, I doubt this article
originated in 2008 as is currently mentioned.

[1] [http://www.unixuser.org/~euske/doc/python/python-
lisp-j.html](http://www.unixuser.org/~euske/doc/python/python-lisp-j.html)

~~~
dang
[https://web.archive.org/web/*/http://norvig.com/python-
lisp....](https://web.archive.org/web/*/http://norvig.com/python-lisp.html)
has 2000 so we can go with that.

------
mkesper
(2000) Sadly there is no date at all in the article.

