473,788 Members | 2,694 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 28743
Paul Rubin wrote:
"Alex Mizrahi" <ud******@users .sourceforge.ne twrites:
"Programmin g Languages:Appli cation and Interpretation"
Shriram Krishnamurthi
Brown University
This book doesn't seem to be online.
http://cs.brown.edu/~sk/Publications/Books/ProgLangs/
Michele Simionato

Dec 11 '06 #381
JS******@gmail. com wrote:
>I challenge anyone making psychological
claims about language X (for any X) being easier to either
read/learn/use than language Y (for any Y) to come up with any valid
evidence whatever.
Put aside,that I don't understand meaning of term
"psychologi cal claim" in that context.
It is obvious that different
medium of information exchange provides
different levels of readability for humans.
And accordingly easier/harder to learn/use.

Regards, Dmitry
Dec 11 '06 #382
(message (Hello 'Paul)
(you :wrote :on '(11 Dec 2006 04:14:20 -0800))
(

??>optimizing language. i think it's called trampolined style.
??>example can be found in PAIP book: interpreter of Scheme is
implemented in

PRThis book doesn't seem to be online. But anyway I think you mean,
PRcompile the Scheme code into one giant CL function, which is no longer
PRreally a clean mapping of Scheme to CL, it's just writing an
PRinterpreter. And I think that interpreter has to do its own
PRmanagement of environments rather than letting the CL runtime do it.
PRSo basically it says CL is turing-complete and can do everything,
PRwhich we already knew ;-).

point is that writting some custom interpreter in CL is very easy AND you
can still use all other features of CL AND communicate with other DSLs.

PRthe different macros being used. But I think I understand one part of
PRwhat was confusing me before: your call/cc macros depend on a
PRnonstandard feature of some CL implementations .

no, it's standard Common Lisp. it's an ARNESI library. it's very standard --
i was able to run non-modified code in Armed Bear Common Lisp implementation
(it's running on JVM), that is very new and does not fully support the
standard -- but nevertheless, CPS code runs out of the box on it.

PR You can't write a call/cc macro in standard CL--you instead have to
PRwrite something that transforms the entire program.

yes, i cannot write just call/cc -- i should wrap code into with-call/cc.
with-call/cc macro performs transformation of the code to CPS -- and then
call/cc is enabled.
i can enable call/cc for specific functions -- i define them with defun/cc
instead of defun. so, i can define both normal CL functions and call/cc
enabled functions. typically, call/cc is required only in a few pieces of
program where interrupts come, so it's OK.

if i'm going to support generators, i only need to run CPS tranformation on
the body of generator function -- that will tear it in yield points.

PRI think even with TCO though, you still can't do coroutines with CL
PRmacros (but you can do them with real call/cc). The point is that you
PRhave to do something like TCO on calls that are not tail calls and
PRactually have to return. You again have to transform the whole
PRprogram, not just expand a call/cc macro locally inside functions that
PRuse it.

i think only functions that are coroutines should be fully transformed.

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"People who lust for the Feel of keys on their fingertips (c) Inity")
Dec 11 '06 #383
Steven D'Aprano schrieb:
On Sat, 09 Dec 2006 14:57:08 -0500, Bill Atkins wrote:
>Paul Rubin <http://ph****@NOSPAM.i nvalidwrites:
>>There is just not that much boilerplate in Python code, so there's
not so much need to hide it.
Well, of course there is. There are always going to be patterns in
the code you write that could be collapsed. Language has nothing to
do with it; Lisp without macros would still be susceptible to
boilerplate.

Here's a concrete example:

(let ((control-code (read-next-control-code connection)))
(ecase control-code
(+break+
(kill-connection connection)
(throw :broken-by-client))
(+status+
(send-status-summary connection))
((+noop+ +keep-alive+))))
;; +X+ indicates a constant

Eight lines, excluding the comment, and it doesn't handle the case where
control-code is not one of +break+, +status+, +noop+ or +keep-alive+,
although the ecase macro does. And how many lines of code is ecase?
>All of that
boilerplate is handled by the macro. In Python, I would need to do
something like:

control_code = connection.read _next_control_c ode()
if control_code == +break+:
connection.kill ()
throw blah
else if control_code == +status+:
connection.send _status_summary ()
else if control_code == +noop+ || control_code == +keep_alive+:
else:
error "CONTROL_CO DE fell through conditional cascade; was not one of +BREAK+, +STATUS+, +NOOP+, +KEEP_ALIVE+"

Your Python syntax is rather wonky, but that's incidental.

Nine lines, including handling the case where control_code is none of the
four constants. Ten if you add the "pass" statement that it actually
needs. And it is completely self-contained, with no external functions or
macros to understand.
Counting source lines is not the important thing. Look at the complexity
and the number of tokens.
The Lisp code is easier, because it is more abstract. You are closer in
saying what you want.

Counting tokens:
(let ((control-code (read-next-control-code connection))) 4
(ecase control-code 2
(+break+ 1
(kill-connection connection) 2
(throw :broken-by-client)) 2
(+status+ 1
(send-status-summary connection)) 2
((+noop+ +keep-alive+)))) 2
======
16
control_code = connection.read _next_control_c ode() 4
if control_code == +break+: 4
connection.kill () 2
throw blah 2
else if control_code == +status+: 4
connection.send _status_summary () 2
else if control_code == +noop+ || control_code == +keep_alive+: 8
else: 1
error "CONTROL_CO DE fell through conditional cascade; 2
was not one of +BREAK+, +STATUS+, +NOOP+, +KEEP_ALIVE+"
======
29
plus a "pass", would make 30 vs 16 "Brain-units".
André
--
Dec 11 '06 #384
"Alex Mizrahi" <ud******@users .sourceforge.ne twrites:
PRthe different macros being used. But I think I understand one part of
PRwhat was confusing me before: your call/cc macros depend on a
PRnonstandard feature of some CL implementations .

no, it's standard Common Lisp. it's an ARNESI library. it's very standard --
The ARNESI doc at:

http://common-lisp.net/project/bese/...sp_to_CPS.html

begins:

By transforming common lisp code into CPS we allow a restricted form
of CALL/CC. While we use the name call/cc what we actually provide is
more like the shift/reset operators (where with-call/cc is reset and
call/cc is shift).

I don't know what shift/reset are but the above says that call/cc in
the Scheme sense is not really implemented. There are also a bunch of
limitations on what can be in the call/cc body, e.g. you can't use
unwind-protect.

Anyway, the nonstandard feature is tail call optimization, if you're
turning continuations into closures, and that's just for the simple
case of dealing with loops written in CPS. E.g.: if you write

(defun sum_to_n (n &optional (acc 0))
;; (sum_to_n n) computes sum of integers from 0 to n
(if (= n 0)
0
(sum_to_n (- 1 n) (+ n acc))))

This function is properly tail recursive (unless I messed up) so with

(sum_to_n 10000000000)

the CPS version is supposed to return the right answer if you wait
long enough. It is not allowed to overflow the stack. This is
guaranteed to work in Scheme but is not guaranteed in CL. And as I
think we agree, with coroutines it gets even worse.
Dec 11 '06 #385
Paul Rubin <http://ph****@NOSPAM.i nvalidwrites:
(defun sum_to_n (n &optional (acc 0))
;; (sum_to_n n) computes sum of integers from 0 to n
(if (= n 0)
0
(sum_to_n (- 1 n) (+ n acc))))
Of course meant:

(defun sum_to_n (n &optional (acc 0))
;; (sum_to_n n) computes sum of integers from 0 to n
(if (= n 0)
acc
(sum_to_n (- 1 n) (+ n acc))))

I've made that same error several times in Haskell as well. I'm not
used to this.
Dec 11 '06 #386
Juan R. wrote:
ph************* @gmail.com ha escrito:
- Lisp is hard to learn (because of all those parenthesis)

I cannot understand why. It is like if you claim that packaging things
in boxes is difficult to learn.

HTML and XML have more brackets than LISP (usually double) for
structuring data and everyone has learned HTML.
I think maybe you missed the point I was making.

To make it clearer I'm saying that the arguments that are being made
over and over again against Lisp in this thread have been the
antithesis of my experience since moving from Python to Lisp.

I just prefer personal experience to popular misconceptions :-)

Phil

Dec 11 '06 #387
Steven D'Aprano schrieb:
With Lisp macros, even that isn't guaranteed. Now, if Lispers would say
"Oh yes, macros give you great power, and with great power comes great
responsibility. Be careful."
Well, macros are one (big) thing that Lisp has and which many other
languages don't have. Their are other things too, and some of them are
in Python as well, which is a very nice scripting language.

Often macros save just some bits of code. Saving one loc is not much you
might say. But think about it the other way around.
How would you like it to call doodleShooble() each time before you use
the if statement? Of course you would not like it. The good thing about
Lisp is, that you can eliminate this pattern.

Apropos pattern.. most design patterns are not (very) visible in Lisp.
Many of them can be abstracted away with macros+function al programming.
André
--
Dec 11 '06 #388
Bill Atkins schrieb:
Bill Atkins <at****@rpi.edu writes:
>"every corner of the language"? Please. Why are you so post-happy
when it's quite obvious that you don't know enough about Lisp to
attack it?

In addition to macros that define classes or methods, a common macro
is the WITH-* macro, which sets up some kind of context, runs the body
inside that context, and then does some cleanup.

For example, my Lisp vendor, LispWorks, provides the macro MP:WITH-LOCK :

(mp:with-lock (*the-big-lock*)
(do-something-atomic)
(something-else)
(almost-odone))

The generated first seizes a process lock called *THE-BIG-LOCK*, runs
the code in the body and then releases the lock. I never have to
worry that I've taken a lock without releasing it, because LispWorks
has encoded that behaviour into MP:WITH-LOCK (and if they handn't,
this macro is trivial to write).

Now I can tell if I'm keeping a lock around too long because all the
code that appears inside this WITH-LOCK is all the code that I'm
locking. Further, the generated code is surrounded by an
UNWIND-PROTECT, which means that if an error is raised or anything
abnormal happens in the dynamic scope of the UNWIND-PROTECT, Lisp will
run cleanup code as it flees back up the stack. So if there is an
error in my code, it does not prevent other processes from seizing
that lock, because it will be released as the error is signaled.

Here is the expansion:

CL-USER 7 (write (macroexpand '(mp:with-lock (*the-big-lock*)
(do-something-atomic)
(something-else)
(almost-odone)))
:pretty t :case :downcase)
(let ((#:g17553 *the-big-lock*))
(when (mp:process-lock #:g17553)
(unwind-protect
(progn (do-something-atomic) (something-else) (almost-odone))
(mp::in-process-unlock #:g17553))))

Now it happens what Graham described. The blub programmer will explain
that this is not needed, because he can do the same thing in blub.

In Python you could write a function withLock that takes a lock and a
function.
Then you can say
def throwAway001():
doSomethingAtom ic()
somethingElse()
almostOdone()

withLock(theBig Lock, throwAway001)
or maybe

withLock(theBig Lock,
lambda ():
doSomethingAtom ic()
somethingElse()
almostOdone())

So Lisp saves you the "lambda ():" or "def throwAway001(): ".
That is nice I would say. Why write it if the computer could do that for
you?
André
--
Dec 11 '06 #389
"Paddy" <pa*******@nets cape.netwrites:
JS******@gmail. com wrote:
Python has to rely more on using the right algorithm...

This sound familiar: "Macros are dangerous!"
Yes. I changed my opinion on advocating Python having macros in one
of our long threads on the subject. Maintainance counts.
Yes, it does, but that should take you to exactly the opposite
conclusion.
>"Compilers make you lazy."
This is new to me. In fact, for the compiled languages available to me.
Using them *first* would be the difficult choice.
These are not real sentences, but if you're saying that compiled
languages make programming more difficult, then you're simply using
the wrong compiled languages. Lisp is a dynamic language that also
supports compilation to native code.
Unlike Lisp, Python does not have a ubiquitous compiler. It is
therefore
made to interface nicely with compiled languages. Other compiled
What on earth does this mean? You're saying that because Python
doesn't have a compiler, it can interface more easily to compiled
languages? That's nonsense.

Further, most Lisp implementations support an interface to C that
doesn't require you to write and compile C code in order to use C
extensions in Lisp. Can Python do the same more "nicely" than Lisp?
language users see the need for dynamic interpreted languages like
Python and maintain links Python such as the Boost Python C++
wrapper. IronPython for .NET, Jython for Java.
Lisp is its own interpreter and compiler, which should be a great
advantage, but only if you don't make the mistake of ignoring the
wealth of code out there that is written in other languages.
Um.
Dec 11 '06 #390

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
10370
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...
0
10177
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10113
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
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...
1
7519
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
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();...
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
2
3677
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2896
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.