473,788 Members | 2,744 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

merits of Lisp vs Python

How do you compare Python to Lisp? What specific advantages do you
think that one has over the other?

Note I'm not a Python person and I have no axes to grind here. This is
just a question for my general education.

Mark

Dec 8 '06
852 28749
"tmh" <tm********@gma il.comwrites:
I've been writing code for engineering solutions for 15 years in
various languages. I've gained more insight into coding in the last 6
months then in the previous 15 years. Since lisp allows you to employ
any and every programming technique, it actually requires you to
understand the techniques well enough to apply them when appropriate.
You might try Mozart, <http://mozart-oz.org>.
You should study lisp for at least a year, use it for some decent size
projects. At the end of the day, even if you decide not to continue
using it, you will be a much better coder. My bet, though, is that if
you use it for a year, you won't want to use anything else.
I've used Lisp for a long time and I've implemented it from scratch
(small dialects, not full CL) more than once. There's something
primordial about it that is very satisfying to the inner urges. But
there are higher forms of life out there these days too.

Do you know the Paul Graham piece "Beating the Averages"? It's at:

http://www.paulgraham.com/avg.html

The error in it is that Lisp is really just another Blub.

http://weblog.raganwald.com/2006/10/...ogrammers.html

Dec 9 '06 #101
On Sat, 09 Dec 2006 02:29:56 -0500, Ken Tilton wrote:
>

David Lees wrote:
Those raving about
Lisp are quite accomplished at all those other languages, and know about
what they are talking.
Such a sweeping generalization. Every person who raves about Lisp is also
accomplished with other languages. Yeah, right. I believe you, even if
millions wouldn't.

I doubt the Pythonistas weighing in on this
thread ever got far at all with Lisp, so... should they really be
offering comparative analysis?
I hit my hand with a hammer once. I didn't keep going until I was an
expert in hitting-own-hand-with-hammer before deciding that hitting my
hand with a hammer was not for me. Did I do the wrong thing? Should I have
kept going until I was an expect at it?

(Of course, writing Lisp isn't precisely like hitting one's hand with a
hammer. With the hammer, the endorphins kick in eventually, and it can
become quite pleasant...)

> Personally, I never like Lisp syntax;
Clearly some people, some fanatic judging by this thread :) think easily
in prefix. I am not one of them.

Yeah, you are, you just did not use it heads down for a month.
The sheer arrogance of this claim is astounding.

Actually, this is comp.lang.lisp. It isn't astounding at all.

I don't know, maybe lisp coders actually are more intelligent than
ordinary mortals, but it has been my experience that they have absolutely
no grasp whatsoever of the way most (many? some?) people think. And I'm
not talking about can't-walk-and-think-at-the-same-time people either, I'm
talking about bright, intelligent people who, nevertheless, don't agree
with lisp coders.

The way
to tell if you spent enough time on Lisp is to look at Lisp code. If you
see any parentheses, you have not spent enough time. They disappear in a
month.
If the parentheses are that meaningless, why do you need them?

The typical Pythonista values clean code but trembles in the face of
macros, which exist to hide boilerplate.
Funny, when I write code, I try to remove boilerplate, not hide it.

That means the only thing
showing in any given block of code is exactly the interesting variable
and function names. Talk about readability.
Yes. And your point is?

>Computer languages are tools and
everyone should pick the ones that they are most comfortable and
productive with.

No, languages are not interchangeable .
Perhaps you should consider what the term "Turing complete" implies.

Python is a fine language, but
Lisp is much more expressive/powerful.
Maybe so. A bulldozer is a lot more powerful than a tack-hammer, but if
somebody suggested using a bulldozer to lay carpet, I'd politely show them
to the door. Sometimes more power isn't better.
--
Steven.

Dec 9 '06 #102
Paul Rubin <http://ph****@NOSPAM.i nvalidwrites:
http://www.math.chalmers.se/~rjmh/Papers/whyfp.html

The examples in it are pretty easy to do in Python or Scheme, but I
think not so easy in CL.
Hmm, well I guess they can be done in CL too, about the same way as in
Scheme, but I'd say you have to be more careful.
Dec 9 '06 #103
(message (Hello 'Kay)
(you :wrote :on '(8 Dec 2006 12:25:09 -0800))
(

KSO.K. I agree with what you said about the generic function vs per
KSobject dictionary dispatch.
KSBut do the performance differences vanish when only builtin types and
KSfunctions are used to express Python algorithms?

no.
language semantics require python to do dict lookup on each access to some
global function (or builtin) or variable.
i don't have enough time for in-depth analysis, but here's what's it.
suppose we have

def Fib(n):
if n < 2:
return 1
else:
return Fib(n -2) + Fib(n-1)

import dis
dis.dis(Fib)

you will see this:
....
21 LOAD_GLOBAL 1 (Fib)
24 LOAD_FAST 0 (n)
27 LOAD_CONST 2 (1)
30 BINARY_SUBTRACT
31 CALL_FUNCTION 1
34 LOAD_GLOBAL 1 (Fib)
37 LOAD_FAST 0 (n)
40 LOAD_CONST 1 (2)
43 BINARY_SUBTRACT
44 CALL_FUNCTION 1
47 BINARY_ADD
48 RETURN_VALUE

now let's check what is LOAD_GLOBAL in ceval.c (i have Python 2.4.1
sources):

case LOAD_GLOBAL:
w = GETITEM(names, oparg);
if (PyString_Check Exact(w)) {
/* Inline the PyDict_GetItem( ) calls.
WARNING: this is an extreme speed hack.
Do not try this at home. */
long hash = ((PyStringObjec t *)w)->ob_shash;
if (hash != -1) {
PyDictObject *d;
d = (PyDictObject *)(f->f_globals);
x = d->ma_lookup(d, w, hash)->me_value;
if (x != NULL) {
Py_INCREF(x);
PUSH(x);
continue;
}
d = (PyDictObject *)(f->f_builtins);
x = d->ma_lookup(d, w, hash)->me_value;
if (x != NULL) {
Py_INCREF(x);
PUSH(x);
continue;
}
goto load_global_err or;
}
}
/* This is the un-inlined version of the code above */
x = PyDict_GetItem( f->f_globals, w);
if (x == NULL) {
x = PyDict_GetItem( f->f_builtins, w);
if (x == NULL) {
load_global_err or:
format_exc_chec k_arg(
PyExc_NameError ,
GLOBAL_NAME_ERR OR_MSG, w);
break;
}
}
Py_INCREF(x);
PUSH(x);
continue;

so we can see PyDict access. moreover, it's inlined, since it's very
performance-critical function.
but even inlined PyDict access is not fast at all. ma_lookup is a long and
hairy function containing the loop.
moreover, we can see that there are two dict lookups -- into globals and
builins.
lookup into a global hash should about order of magnitude slower than simple
table fetch, so here's the root of python's slowness.

how lisp can be faster here? lisp has SYMBOLs and well-defined semantics of
source code parsing.
first source code is processed by reader, that outputs trees of code. each
variable or function name becomes a SYMBOL object. symbols are typically
interned into packages, but they don't need to be looked-up in the packages
in runtime -- in fact, it's not possible at all.
i can read a piece of code and then unintern some symbol from package --
that will not make that code invalid. packages are used mostly by reader.
(also, i can have many symbols with same name, if they are not interned --
and they will be all different objects)
in runtime, lisp has to lookup symbol's function -- but symbol can be
implemented as a structure, and symbol-function can be just it's field
access.

one more thing -- you can see lookup into builins, so they are in dict too!
and you can see that builtins dict is checked only if name is not found in
globals, so builtins are even slower than globals. that's a reason for
performance slowdowns too.
one can say that it's the only way to change builtins in runtime. yes, but
dict lookup is a big price for it (well, if python use symbols, it would be
faster).
in fact, Common Lisp also allows to redefine "built-in" function -- you can
define a symbol with a same name as builtin in some package and use it, it
will "shadow" symbol in the common-lisp package (common-lisp:+). you can
change symbol-function of this symbol in runtime and do whatever you want.
but symbols in common-lisp package are immutable. that makes it possible to
optimize code.

and there's inlining. for example, in fib definition:

(defun fib (n)
(if (< n 2)
1
(+ (fib (- n 2))
(fib (- n 1)))))

CLISP does not even use symbol FIB in function bytecodes -- it notes that
it's a recursive function calls, so instead of normal function call it does
a local jump.

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"People who lust for the Feel of keys on their fingertips (c) Inity")
Dec 9 '06 #104
On Fri, 08 Dec 2006 23:38:02 -0800, Wolfram Fenske wrote:
if Common Lisp didn't have CLOS, its object system, I could write my own
as a library and it would be just as powerful and just as easy to use as
the system Common Lisp already provides. Stuff like this is impossible
in other languages.
Dude. Turing Complete. Don't you Lisp developers know anything about
computer science?

Anything any language can do is possible in any other language, if you are
willing to write your own libraries. And debug them. Let's not forget the
debugging and testing, unless you'd like us to believe that Lisp code
never contains bugs. Lisp developers so often gloss over that: "Oh,
feature X is *easy*, I could write it in a couple of macros. Two or three.
Maybe thirty. Or forty, max. And they would work the right way first time.
No, I haven't actually done it myself. But I'm sure I could do it, easy."

--
Steven.

Dec 9 '06 #105


Steven D'Aprano wrote:
It is a good thing that not every
hare-brained idea that some random programmer comes up with can be
implemented as part of the core language.
Well, that's the FUD/strawman, but nothing more. Just a hobgoblin to
keep the Pythonistas from straying. But you have an excuse: Lispniks
always /talk/ about macros giving us the ability to create a DSL. But no
one does. :) Macros mostly hide implementation -- always a good thing --
where functions cannot.

This, btw, is why Norvig brushing off macros with the ability to use
regex to parse a DSL was so disappointing.

I guess your other excuse is that your BDFL says the same thing.

All in all, this is getting pretty funny. I am starting to picture you
all (including GvR) running around with your hands over your ears going
woo-woo so you cannot hear what we are saying.

:)

ken

--
Algebra: http://www.tilton-technology.com/LispNycAlgebra1.htm

"Well, I've wrestled with reality for thirty-five
years, Doctor, and I'm happy to state I finally
won out over it." -- Elwood P. Dowd

"I'll say I'm losing my grip, and it feels terrific."
-- Smiling husband to scowling wife, New Yorker cartoon
Dec 9 '06 #106


Paul Rubin wrote:
>
Do you know the Paul Graham piece "Beating the Averages"? It's at:

http://www.paulgraham.com/avg.html

The error in it is that Lisp is really just another Blub.

http://weblog.raganwald.com/2006/10/...ogrammers.html
There we find: "But when our hypothetical Blub programmer looks in the
other direction, up the power continuum, he doesn't realize he's looking
up. What he sees are merely weird languages... Blub is good enough for
him, because he thinks in Blub."

What is up the power continuum from Lisp?

ken

--
Algebra: http://www.tilton-technology.com/LispNycAlgebra1.htm

"Well, I've wrestled with reality for thirty-five
years, Doctor, and I'm happy to state I finally
won out over it." -- Elwood P. Dowd

"I'll say I'm losing my grip, and it feels terrific."
-- Smiling husband to scowling wife, New Yorker cartoon
Dec 9 '06 #107
(message (Hello 'Paul)
(you :wrote :on '(08 Dec 2006 17:15:32 -0800))
(

PRHuh? Are you saying Lisp systems never release new versions? And you
PRcan't implement Python generators as Lisp macros in any reasonable
PRway. You could do them in Scheme using call-with-current-continuation
PRbut Lisp doesn't have that.

we can implement Scheme's call-with-current-continuation first :)
it's relatively easy -- just a code walker that coverts everyting into CPS.
i've used one for a web application development.

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"People who lust for the Feel of keys on their fingertips (c) Inity")
Dec 9 '06 #108
On 08 Dec 2006 19:56:42 -0800, Paul Rubin
<"http://phr.cx"@nospam. invalidwrote:

(...)
Lisp just seems hopelessly old-fashioned to me these days. A
modernized version would be cool, but I think the more serious
Lisp-like language designers have moved on to newer ideas.
Paul, I find most of your comments well thought. But I don't follow
these. Could you elaborate?

a) "old-fashioned"? Is that supposed to be an argument? I guess
addition and multiplication are old-fashioned, and so is calculus;so?
I think "old-fashioned" should only carry a negative connotation in
the fashion world, not in programming.
b) "the more serious Lisp-like language designers have moved on to
newer ideas." Can you elaborate? I am not an expert but by looking at,
say, lambda the ultimate, I'd say this statement is just not true. And
which are these "newer ideas"; what programming languages are
incorporating them? (Scala, Mozart/Oz, Alice-ML, ...).
R.

--
http://mail.python.org/mailman/listinfo/python-list

--
Ramon Diaz-Uriarte
Statistical Computing Team
Structural Biology and Biocomputing Programme
Spanish National Cancer Centre (CNIO)
http://ligarto.org/rdiaz
Dec 9 '06 #109
Alex Mizrahi wrote:

....
so we can see PyDict access. moreover, it's inlined, since it's very
performance-critical function.
but even inlined PyDict access is not fast at all. ma_lookup is a long and
hairy function containing the loop.
I once had a crazy idea about the lookup speed problem;
can't the lookup result be cached in the bytecode ?
I am thinking to something like saving a naked pointer
to the value together with a timestamp of the dictionary.
With timestamp I mean an integer (may be 64 bit) that is
incremented and stamped in the dictionary every time
the dictionary is modified; this counter can be
shared among all dictionaries. The use of a naked pointer
would be IMO safe because to invalidate the object you
would also need to touch the dictionary.

Using this approach the lookup for a constant
string could be

if (bytecode_times tamp == dict->timestamp)
{
// just use the stored result
}
else
{
// do standard lookup and store
// result and dict->timestamp
}

I'd expect that this would be a big win for a lot of
lookup as the problem with python speed is the *potential*
dynamism... hopefully people don't keep changing what
math.sin is during the execution so the vast majority of
lookups at module level will find the timestamp being valid.
This invalidation is not "optimal" as changing math.sin
would also invalidate any lookup on math, but IMO a lot
of lookups happen in *fixed* dictionaries and the the
overhead of checking the cached result first should be
small. What it would break is code that actually
dynamically changes the string being looked up in the
dictionary in the bytecode, but I hope those places
are few if the exist at all.

Is this worth investigation or it has already
been suggested/tried ?

Andrea
Dec 9 '06 #110

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
2190
by: Paddy3118 | last post by:
This month there was/is a 1000+ long thread called: "merits of Lisp vs Python" In comp.lang.lisp. If you followed even parts of the thread, AND previously used only one of the languages AND (and this is the crucial bit), were persuaded to have a more positive view of the other language; (deep breath, this is a long, as well as grammatically incorrect sentence), THEN WHY NOT POST ON WHAT ARGUMENTS PERSUADED YOU.
0
10373
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10118
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9969
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8995
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6750
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5403
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5538
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4074
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2897
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.