merits of Lisp vs Python

J

Jon Harrop

Bill said:
Despite its dynamism, Lisp is quite compilable. For example, I can
redefine classes, functions, macros, etc. at runtime and compiled code
referring to the old code will still work. You are conflating
dynamism with interpretedness, and that's incorrect.

There is clearly a trade-off. Look at my ray tracer benchmark, for example:

http://www.ffconsultancy.com/free/ray_tracer/languages.html

The static languages are significantly faster.

I think Python can hope to be as fast as SBCL-compiled Lisp, after a huge
amount of work on Python compilers, but it will never be as fast as the
compiled static languages.

On that ray tracer, Python might be able to approach OCaml's brevity but it
will be orders of magnitude slower as long as it is interpreted. Compiling
Python to a decent bytecode might give better performance, but OCaml
bytecode is 30x slower than native code on this benchmark.
 
P

Paul Rubin

Rob Thorpe said:
But in that case what do you call Python? The whole language has no
standard - is it an "implementation dependent hack"?

This is one of my perpetual complaints about Python. It does have a
reference manual and library manual, but these manuals are full of
gaps, and in practice one does go by the implementation. CLTL2 is a
model of precision and thoroughness compared with any document that's
ever been written about Python.
 
J

Jon Harrop

André Thieme said:
Contrast the much more common

a = b[n]

with

(setf (aref a i) (aref b n))

and the attractions of Python may make more sense.


Here Python and Lisp are equal, 7 tokens vs 7 tokens, but in Python
one has to write less since "[]" are 2 chars while "aref" are 4, plus
the setf.


Why are you not counting Lisp's superfluous parentheses but you are counting
the brackets in the Python? I get 9 tokens for Python vs 13 for Lisp.
But from counting the brain units which I regard as an important factor
they are both equal.

Python is clearly more succinct in this case. I also think it is worth
counting chars or LOC as well as tokens. Lisp has unnecessarily long
built-in tokens...
 
P

Paul Rubin

Ken Tilton said:
That was my stance for about seven years of intense Lisp. Then the
author of Practical Common Lisp did a nice job of breaking the whole
mess up into sensible chunks and I picked it up. If one programs Lisp,
one should learn Loop -- it is definitely worth the bother. I def
regret not learning it sooner.

I don't really code in Lisp any more, I never felt a need for loop
when I was coding in Lisp, and I'm trying to move towards a style of
programming without loops (i.e. I'm playing with Haskell, which
doesn't have loops), giving me even less need for a hairy loop macro.
 
R

Robert Uhl

Bjoern Schliessmann said:
Erm ... because there's an editor for it that indents automatically?

Because it's the language for which indentation is automatically
determinable. That is, one can copy/paste a chunk of code, hit a key
and suddenly everything is nicely indented.
 
P

Pillsy

Ken Tilton wrote:
[...]
That was my stance for about seven years of intense Lisp. Then the
author of Practical Common Lisp did a nice job of breaking the whole
mess up into sensible chunks and I picked it up. If one programs Lisp,
one should learn Loop -- it is definitely worth the bother. I def regret
not learning it sooner.

When I first read PCL (which was my introduction to Lisp) I thought
LOOP was really neato. Once I actually started using it for things that
weren't so simple, I began to really hate it. I think that having a
specialized mini-language for iteration is a superb idea, but I don't
think LOOP is it.

That being said, there's a portable alternatives out there that I like
way better, and I still use LOOP for dashing stuff off one-liners at
the REPL.

Cheers,
Pillsy
 
P

Petter Gustad

Robert Uhl said:
that for can understand new objects; CL LOOP is not extensible, unless I
have missed something big, but it's simple enough to write a
map-new-object or loop-new-object or whatever).

There is no standard way to extend loop, but most of the major vendors
let you extend it using add-loop-path. In CLSQL you can do stuff like

(loop for (time event) being the tuples of "select time,event from log"
from *my-db*
do ... )

Petter
 
R

Robert Uhl

Steven D'Aprano said:
Speaking as somebody who programmed in FORTH for a while, that doesn't
impress me much. Prefix/postfix notation is, generally speaking, more
of a pain in the rear end than it is worth, even if it saves you a
tiny bit of thought when pasting code.

Of course, you use prefix notation all the time in Python:

for x in range(0,len(y)):
dosomething(x)

In the example, 'for,' 'range,' 'len' and 'dosomething' all use
prefix notation. In Lisp the example might look like this, assuming the
proper functions and macros to make it work:

(for ((x (range 0 (length y))))
(dosomething x))

Slightly more idiomatic would be:

(loop for x in (range 0 (length y))
do (dosomething x))

Even more idiomatic would be:

(loop for x below (length y)
do (dosomething x))

Which doesn't seem particularly more or less prefixy or infixy than the
Python version.

Infix is really only used in arithmetic--and there are Lisp macros which
give one infix notation if wanted, so one could write:

(infix 1 + x / 4)
 
P

Pascal Costanza

Pillsy said:
Ken Tilton wrote:
[...]
That was my stance for about seven years of intense Lisp. Then the
author of Practical Common Lisp did a nice job of breaking the whole
mess up into sensible chunks and I picked it up. If one programs Lisp,
one should learn Loop -- it is definitely worth the bother. I def regret
not learning it sooner.

When I first read PCL (which was my introduction to Lisp) I thought
LOOP was really neato. Once I actually started using it for things that
weren't so simple, I began to really hate it. I think that having a
specialized mini-language for iteration is a superb idea, but I don't
think LOOP is it.

That being said, there's a portable alternatives out there that I like
way better, and I still use LOOP for dashing stuff off one-liners at
the REPL.

If you hate LOOP then you don't have to use it.

There's an important lesson to learn here: Not all language constructs
are supposed to be loved by everyone. ;)


Pascal
 
R

Robert Uhl

HowiPepper said:
I have checked out Lisp several times in the past, but I always get
turned off completely by the parenthesis you have to use for
everything. What's up with that anyway?

It's no different from having to use newlines and spaces and square
brackets and parentheses in Python. E.g. the Lisp (f x y) is exactly
equivalent to the Python f(x, y); the Lisp (if x y z) is exactly
equivalent to the Python:

if x:
y
else:
z

There is, though, an advantage: (f x y) and (if x y z) aren't just parts
of programs--they're also lists. That means that one can use all the
list-manipulation primitives on a program, and thus that it's very easy
to write programs which manipulate programs. This in turn leads to
being able to extend the syntax of the language. Imagine if one could
write this in Python:

defsyntax unless(condition, commands):
if not condition:
commands

And use it like this:

unless day == 'Sunday':
work()

That'd be pretty cool, right? After all, 'unless day is Sunday' conveys
the sense of what you're doing a little better than 'if days is not
Sunday.' But in Python it's not possible--even my defsyntax example is
absurd: how would the compiler know the difference between pre-colon
argument and the command block? What if I wanted multiple blocks
(e.g. as with an else:)?

Whereas with Lisp one might simply write:

(defmacro unless (condition &body commands)
`(if (not ,condition)
,@commands))

When used as:

(unless (equal day "Sunday")
(work))

The compiler transforms it into:

(if (not (equal day "Sunday"))
(work))

This is a _really_ simple example (unless is nice, but it's hardly
vital); but what one can do is end up making a much more declarative
program by creating new syntax to describe stuff.
With Python's ease of learning and use, availability of a large number
of libraries, extremely active development community and large
user-base, I'd say the question to ask is what specific advantages
over Python does Lisp offer, to make people switch to it?

Well, these come to mind; they're in no order and are just my own
particular thoughts. No doubt more reflective commentators can come up
with a better list.

o Macros

As mentioned above, macros can make one's life significantly nicer. I
use Python a lot (it's currently a better choice than Lisp for many of
the problems I face), and I find myself missing macros all the time.
The ability to take some frequently-used idiom and wrap it up in a macro
is wonderful. E.g. a common idiom in Python is:

file = open(path, 'r')
for line in file.readlines():
foo(line)
bar(line)
baz(line)

Even this isn't much nicer:

for line in open(path, 'r').readlines():
foo(line)
bar(line)
baz(line)

Wouldn't it be nice to have a macro with-open-file?

filefor line in path:
foo(line)
bar(line)
baz(line)

o Speed

Lisp interpreters are several orders of magnitude faster than Python,
and Lisp compilers are faster yet. Speed's not the most important
thing, but it is _an_ important thing; all other things being equal, the
faster solution is better.

o Symbols

In Lisp, a symbol is essentially a hashed string; two symbols are alike
if their names are alike, but comparison of symbols is a constant-time
operation. Thus where in Python I have lots of string comparisons for
constants, and in C I have #defined integers, in Lisp I have symbols.
It's not just a performance hack--symbols are part of why macros and
packages work--but when I miss them, I miss them for the performance
side of things

o CLOS

The Common Lisp Object System is a really remarkable piece of work.
Among other things, it has generic functions instead of methods.
E.g. in Python or most other OO languages object.method(arg1, arg2) is
really just a fancy piece of syntactic sugar for method(object, arg1,
arg2); method does different things depending on the type of object, its
first argument.

Wouldn't it be nice to be able to specialise a method on _any_ subset of
its arguments, not just its first one? Well, CLOS offers that. (method
object1 object2) could be specialised on the first argument, the second
or both. This can be very powerful.

Wouldn't it be nice to specify that some action be taken before or after
a superclass's method, rather than over-riding that method entirely?
Sure, one can over-ride the method and then call it within one's own
code, but that obscures the meaning of what one's doing.

o CLSQL

An OR mapper which actually works. 'Nuff said.


OTOH, here's what Python offers which Lisp doesn't:

o A capable standard library

Lisp's standard library was considered large once upon a time--why, it
included lists and hashes! But that's not a big deal nowadays. Right
now there are a plethora of choices, but it's not clear which choices
are blessed or particularly good. Sure, once could use a different MIME
library than Python offers as standard, but it's good to know that there
_is_ a standard.

o A large, friendly community

Lisp's community is small and exceedingly bright; it doesn't suffer
fools gladly. Python's is larger and friendlier, realising that we were
all fools once and that with education many of us get better.

o Top-notch Web frameworks

Pylons and Django are nice to use and take care of a lot of the
boilerplate one would otherwise have to write. While Webactions is a
very cool framework, it lives at a lower level and there's a lot more
one has to add to it for a complete app.
 
P

Pillsy

Pascal said:
Pillsy wrote: [...]
When I first read PCL (which was my introduction to Lisp) I thought
LOOP was really neato. Once I actually started using it for things that
weren't so simple, I began to really hate it. I think that having a
specialized mini-language for iteration is a superb idea, but I don't
think LOOP is it.
That being said, there's a portable alternatives out there that I like
way better, and I still use LOOP for dashing stuff off one-liners at
the REPL.
If you hate LOOP then you don't have to use it.

Indeed, I *don't* use it except for the simplest things.
There's an important lesson to learn here: Not all language constructs
are supposed to be loved by everyone. ;)

Especially in Common Lisp, where it's possible to have replacements
that integrate with the rest of the language as seamlessly as the
original feature they're replacing.

I don't love CL because its devoid of features I hate. I love it
because it provides so many great ways of getting around the features I
hate. If it didn't have features I hate, I might actually like it less,
because I wouldn't have anything to bitch about on USENET. :)

Cheers,
Pillsy
 
P

Paul Rubin

jayessay said:
Agreed. Indeed, that was the underlying guiding principle in putting
together CL. *ML being older than CL didn't have any more opportunity
in this respect.

You're forgetting that CL tried to be more or less backwards
compatible with its predecessors, at least compatible enough that
large systems in Maclisp, Interlisp, Zetalisp, etc. could be ported
without too much pain. Therefore, CL could not erase too many
mistakes from the past. Scheme went somewhat further than CL at
cleaning things up, and Scheme's aficionados think CL is a clumsy old
kludge as a result. But it's still a Lisp dialect. The ML's, for
their part, were able to start from scratch.
 
R

Robert Uhl

Paul Rubin said:
Huh? Are you saying Lisp systems never release new versions?

The Common Lisp standard hasn't been updated in over a decade.
Moreover, one doesn't need to wait for a standard to add syntax--one
just adds it and gets on with solving the problem at hand.
And you can't implement Python generators as Lisp macros in any
reasonable way.

I'm pretty certain it could be done with conditions.
 
R

Robert Uhl

Steven D'Aprano said:
It is a good thing that when Fred decides to stop contributing to an
open source project (or leave the company), other people can read his code
without having to learn his Uber-Special Custom Macro Extended
Language.

And yet they have to learn his Uber-Special Custom Function Extended
Language. If adding syntax is bad, surely adding functions is bad too.
And yet, I don't see very many people arguing for a return to
unstructured code.

In fact, the ability to add syntax is as important as the ability to add
functions; it's a second order of structure.
 
R

Robert Uhl

Ravi Teja said:
By that standard, every other mainstream dynamically typed language
for you is a cut-down version of Lisp with worse performance.

Pretty much;-)

Fewer features, worse performance. Why use 'em? In my case, because
the standard library is larger, and because I can get my teammates to
use 'em.

--
Robert Uhl <http://public.xdi.org/=ruhl>
When you disarm your subjects you offend them by showing that either
from cowardliness or lack of faith, you distrust them; and either
conclusion will induce them to hate you.
--Niccolo Machiavelli, The Prince
 
J

jayessay

Paul Rubin said:
You'd have to compare (say) OCaml to CL if it's dialect against
dialect. If you're going to bring in the earlier ML family you also
have to bring in Lisp 1.5, which goes much further back than CL.

Fair enough. But really, I don't see any of these things as
particularly "modern" (whatever that means) or groundbreaking.
Certainly not at this point.

Also, there is the issue of whether there even is a "continual
progression", as in "moving up some ladder" towards something
"better", in the context of programming languages. All of that is
pretty fuzzy stuff, and plenty of CogSci work has shown these value
judgements in this context to be less than obvious in any meaning.

There is also a question about "old/new" wrt these value judgements.
Since Lisp is (admittedly some hand waving here) more or less lambda
calculus embodied, is it closer to say The Calculus or Group Theory
than to some random piece of technology?[1] If Lisp is "old
fashioned", then The Calculus and Group Theory are like _really_ old
fashioned. But does that lessen them in some way? What would that
be? Is some random "new" technique (say brute force iterative
techniques for calculus problems with computers) somehow "better"?


/Jon

1. Of course, the _implementations_ are random pieces of technology.
 
R

Robert Uhl

Consider this: Lisp has had years of development, it has had millions of
dollars thrown at it by VC firms -- and yet Python is winning over Lisp
programmers. Think about it.

The argument from popularity is invalid. French units have overtaken
standard units, yet they are technically worse. Windows has overtaken
Unix, yet it is technically worse.

The market does not select the technically best (although it may select
what is best when all factors are taken into account; e.g. Windows may
be better when dealing with an ignorant workforce, and French units may
be better when dealing with users thereof).

--
Robert Uhl <http://public.xdi.org/=ruhl>
Traditionally, there are only three classes of people who use 'we' in
describing themselves: Royalty (which you aren't), editors (no evidence
that this applies) and people with tapeworms. Please let us know when
you've been cured. --Hal Heydt, to Dennis O'Connor
 
J

jayessay

Paul Rubin said:
If you say foo.frob() in Python, that's supposed to look up 'frob' in
a dictionary hanging off of foo. You can modify the contents of this
dictionary any time you want.

Unless I'm missing something this looks absolutely dead easy to
implement in Lisp and with a very little macrology you would have the
syntax as well. I'm not sure how this makes one or the other "more
dynamic".

The Lisp equivalent would be some generic function (frob foo)...

I would say the Lisp equivalent would be to literally do exactly the
same thing. Of course, as you say, maybe doing this doesn't actually
make any sense and so it wouldn't get done...


/Jon
 
G

George Sakkis

Robert said:
o Macros

As mentioned above, macros can make one's life significantly nicer. I
use Python a lot (it's currently a better choice than Lisp for many of
the problems I face), and I find myself missing macros all the time.
The ability to take some frequently-used idiom and wrap it up in a macro
is wonderful. E.g. a common idiom in Python is:

file = open(path, 'r')
for line in file.readlines():
foo(line)
bar(line)
baz(line)

Even this isn't much nicer:

for line in open(path, 'r').readlines():
foo(line)
bar(line)
baz(line)

Wouldn't it be nice to have a macro with-open-file?

filefor line in path:
foo(line)
bar(line)
baz(line)

You probably need to refresh your Python skills if you want to be more
productive in it. Files have been iterable for the last couple of years
(since 2.1-2.2, don't remember).

for line in open(path):
foo(line)
bar(line)
baz(line)

You can also iterate through the lines of more than one files using the
fileinput module (http://docs.python.org/lib/module-fileinput.html):

import fileinput

# iterate over the lines of the files passed as command line
# arguments (sys.argv[1:]) or sys.stdin for no arguments
for line in fileinput.input():
foo(line)


I'm sure there should be more convincing examples for macros, but
neither this nor the 'unless' syntax sugar cuts it.

George
 
R

Robert Uhl

Neil Cerutti said:
I got stuck (last year) in that book:

http://www.gigamonkeys.com/book/practical-a-portable-pathname-library.html

The author didn't do Common Lisp (or me) any favors by drawing my
attention to the pathname library.

Yeah, I think his intent was for it to be a nice little practicum to
demonstrate how to use the language--unfortunately it dealt with one of
the uglier bits of CL. The fact that pathnames are really cool doesn't
fix the problem that they are at once overspecified and underspecified.

If the standard were revised, that'd be a good candidate right there.
This is where having a benevolent dictator for life comes in handy.
I suppose I missed whatever the point was supposed to be in the midst
of the mind-boggling. I meant to get back to it but haven't yet.

I pretty much skipped that chapter. The bit where it gets mind-boggling
is where he creates ID3-tag reading classes from binary-reading
primitives and ends up with a complete ID3 library in very few lines of
code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,434
Messages
2,571,690
Members
48,796
Latest member
Greg L.

Latest Threads

Top