473,750 Members | 2,515 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 28568
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

The standard ECASE macro encapsulates this pattern: Compare the
variable control-code to +break+. If the two are EQL, then run the
code provided in the +break+ clause. Likewise for +status+. In the
last clause, the test-form is a list, so the generated code will
compare control-code to either +noop+ or +keep-alive+. If it is EQL
to either, it runs the body of that clause, which happens to be blank
here. The E in ECASE stands for "error," so if control-code doesn't
match any of these choices, the generated code will signal an error
with the following text "CONTROL-CODE fell through ECASE expression;
was not one of: +BREAK+, +STATUS+, +NOOP+, +KEEP-ALIVE+". 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+"

To change what control codes you want to check for, you need to add
conditionals for them and keep the error text relevant. The reality
is that a computer could be doing this for you, leaving your code
simpler and more easily changed.

Now someone will complain that the ECASE code means nothing until I
understand ECASE. Yep. But once you understand ECASE, you can look
at that code and, *at a glance*, see how control flows through it. In
the equivalent Python code, I need to walk through each conditional
and make sure they're all following the same pattern. If you're not
convinced, extend the example to 12 different control codes.

Note also that ECASE is just expanding to the COND conditional. There
is nothing mind-bending (or even mind-twisty) going on inside of it.
It's simply a way of expressing a common syntactic pattern in
higher-level terms. To prove that macros are not the frightening
beasts you guys are making them out to be:

CL-USER 13 (let ((*print-case* :downcase))
(pprint (macroexpand '(ecase control-code
(+break+
(kill-connection connection)
(throw :broken-by-client))
(+status+
(send-status-summary connection))
((+noop+ +keep-alive+))))))

(let ((#:g17558 control-code))
(case #:g17558
(+break+ (kill-connection connection) (throw :broken-by-client))
(+status+ (send-status-summary connection))
((+noop+ +keep-alive+))
(otherwise (conditions::ec ase-error #:g17558 '(+break+ +status+ (+noop+ +keep-alive+))))))

If you treat the #:G17548 as just a weirdly-named variable, you can
see that the code is just expanding into the standard CASE macro. I
can in turn expand this CASE to:

CL-USER 14 (let ((*print-case* :downcase))
(pprint (macroexpand '(case #:g17558
(+break+
(kill-connection connection) (throw :broken-by-client))
(+status+
(send-status-summary connection))
((+noop+ +keep-alive+))
(otherwise (conditions::ec ase-error #:g17558 '(+break+ +status+ (+noop+ +keep-alive+))))))))

(let ((#:g17559 #:g17558))
(cond ((eql '+break+ #:g17559) (kill-connection connection) (throw :broken-by-client))
((eql '+status+ #:g17559) (send-status-summary connection))
((or (eql '+noop+ #:g17559) (eql '+keep-alive+ #:g17559)) nil)
(t (conditions::ec ase-error #:g17558 '(+break+ +status+ (+noop+ +keep-alive+))))))

COND is the Lisp conditional form.

As you can see, ECASE does not blow your mind, but simply names and
standardizes a common pattern of code. It expands into standard
macros. And ECASE is so easy to write that most Lisp programmers have
extended versions of it in their personal libraries. And most of
these are named GENERIC-CASE or STRING-CASE, etc. and most expand into
standard COND, CASE or ECASE macros. We are not going crazy and
definining new langauges; we are simply extending Lisp to meet our
needs, by creating macros that abstract common patterns. In many
cases, the macros resemble standard, well-known Lisp macros even down
to their names.

(In the real world, I might use CLOS's eql-specifiers to define
handlers for each kind of control code. But Python doesn't have
anything analagous to that, so I'll be polite and pretend I have to
use ECASE).
Dec 9 '06 #161
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))))
Dec 9 '06 #162
In article <11************ **********@j44g 2000cwa.googleg roups.com>,
"mystilleef " <my********@gma il.comwrote:
1). More and better mature standard libraries (Languages don't matter,
libraries do).
.....
On Lisp Macros:

I think they are overrated, and in general cause more harm than good.
It's the reason I find Lisp-like programs difficult to grok, maintain
and extend. Cos every smart ass wants to needlessly write his own mini
language to the point of absolute obfuscation. Naturally, I'm supposed
to be awed by his mischievous cleverness.
I've not seen a convincing explanation as to why imported macros
from some library are so much more evil than imported functions. In
both cases one might have to dig into documentation and/or comments
to understand exactly what that imported snippit is doing.
Dec 9 '06 #163
Kirk Sluder <ki**@nospam.jo bsluder.netwrit es:
In article <11************ **********@j44g 2000cwa.googleg roups.com>,
"mystilleef " <my********@gma il.comwrote:
>1). More and better mature standard libraries (Languages don't matter,
libraries do).
....
>On Lisp Macros:

I think they are overrated, and in general cause more harm than good.
It's the reason I find Lisp-like programs difficult to grok, maintain
and extend. Cos every smart ass wants to needlessly write his own mini
language to the point of absolute obfuscation. Naturally, I'm supposed
to be awed by his mischievous cleverness.

I've not seen a convincing explanation as to why imported macros
from some library are so much more evil than imported functions. In
both cases one might have to dig into documentation and/or comments
to understand exactly what that imported snippit is doing.
And the difference with a library function is?

(defpackage "LIBRARY" (:export "THIS-IS-A-FUNCTION"))

(library:this-is-a-function ???) ; ???

--
__Pascal Bourguignon__ http://www.informatimago.com/

"This statement is false." In Lisp: (defun Q () (eq nil (Q)))
Dec 9 '06 #164


Pascal Bourguignon wrote:
Kirk Sluder <ki**@nospam.jo bsluder.netwrit es:

>>In article <11************ **********@j44g 2000cwa.googleg roups.com>,
"mystilleef " <my********@gma il.comwrote:

>>>1). More and better mature standard libraries (Languages don't matter,
libraries do).

....
>>>On Lisp Macros:

I think they are overrated, and in general cause more harm than good.
It's the reason I find Lisp-like programs difficult to grok, maintain
and extend. Cos every smart ass wants to needlessly write his own mini
language to the point of absolute obfuscation. Naturally, I'm supposed
to be awed by his mischievous cleverness.

I've not seen a convincing explanation as to why imported macros
from some library are so much more evil than imported functions. In
both cases one might have to dig into documentation and/or comments
to understand exactly what that imported snippit is doing.


And the difference with a library function is?
Uh, that was his point.

And if you all dig back thru this thread you will find me quoting GvR on
the difference, which is (paraphrasing) "with macros you do not even
know where the function calls are". I think he is talking about a
loop-like erection of a new language.

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 #165
Bill Atkins wrote:
Are any of these not subjective?
Objectivity is in the eye of the beholder.
Lisp is much more than a functional language.
Maybe so. But I've only ever appreciated its functional aspects. I
wouldn't choose Lisp or its derivatives for OO related tasks even if
I'm high.
Uh huh. Can you cite examples of this? Sounds like you're just
making stuff up here. Contrary to popular belief, writing a Lisp
macro that warps your mind and introduces a totally un-CL-like
semantics is extremely difficult. Most of the people who are good
enough at CL to do it (I'm certainly not one of them) are also
experienced enough to know when it's the right choice.
Any sizable Lisp applications will make extensive use of macros. Emacs
and magic ( the web framework) come to mind. My experience has shown
that nobody but the person who writes the DSL extension can maintain
their code. The benefits of extending a language in a domain specific
manner are exaggerated. My observation is that macros are important to
Lisp and it's derivative because they lack libraries to begin with.
Common problems solved using macros in Lisp and friends are solved
using specialized libraries in most other languages. And I like the
specialized libraries route. Meta-programming just doesn't tickle my
fancy. It just spells maintainance nightmare.
And Lisp environments all support getting the macroexpansion,
documentation, and source of any unfamiliar macro you might happen
upon, so really this is not as much of a problem as you might
fantasize it to be.
How's this a good thing? I don't need a Python environment to grok
Python code.
I don't agree with a lot of what you say in this paragraph, but I
you're right that libraries are crucial. That's why I wish there were
more people writing Lisp libraries instead of being scared away by
sheer fabrications like the stuff that's appearing in this thread.
People only contribute to things they understand and appreciate. More
people would be writing Lisp libraries if it was worthwhile.
Apparently, it doesn't seem to be. A few years ago, I tried to write an
editor is Scheme. The experience was appalling. I was able to write a
fully functional prototype editor in less than a week in Python.
Shockingly, at the time, I had no experience in Python. Guess which
community I was inclined to contribute to afterwards. I hear stories
similar to mine time and again, yet the Lisp community won't take heed.
They'd rather squeal about the superiority of macros and whine about
their frustrations in Python news groups.

Dec 9 '06 #166
I think that people who know more languages and more about programming will
be much more inclined to use Lisp than Python. Look at the contents of the
newsgroups for example, c.l.l has a thread on memoization whereas c.l.p has
a thread about wrestling oiled pigs.
Practicality beats purity. :)

--
mvh Björn
Dec 9 '06 #167

Paul Rubin <http://ph****@NOSPAM.i nvalidwrites:
For a long time Scheme had no macros, and Scheme developers who were
exceedingly familiar with Common Lisp were nonetheless willing to get
by without them. So I have to think macros aren't all THAT important.
Scheme did eventually get macros, but somewhat different from CL's.
Macros are important enough that all the old Scheme implementations I used
offered macros in the style of Lisp's defmacro. Lisp hackers did not have
to suffer without them when writing Scheme code.

Relatively recently, the Scheme standard was augmented with hygenic macros,
a different beast. Scheme standardizes something only when there's nearly
universal support for it, so features appear in the language standard very
slowly.

bob
Dec 9 '06 #168
In article
<pa************ *************** *@REMOVE.THIS.c ybersource.com. au>,
Steven D'Aprano <st***@REMOVE.T HIS.cybersource .com.auwrote:
Now, if you want to tell me that, despite all the talk, Lisp coders don't
actually create new syntax or mini-languages all that often, that they
just use macros as functions, then the question becomes: why do you need
macros then if you are just using them as functions? Why not use functions?
Well, as a user of both lisp and python, it seems to me that python
programs can create their own domain-specific mini-languages using
mechanisms such as objects, classes and functions. It's quite
possible to mask the bare-bones python behind functions and objects
derived from imported libraries, which themselves might not be
python-native. And extreme advocates of functional programming
raise the same arguments about objects: they create obfuscated
constructs that are difficult to read and understand without
unpacking their internals. The questions could be asked, why do you
need objects if you are just using them as containers for functions?
Why not just use functions?

Python already is very explicit about supporting OOP, a paradigm
that bundles functions and data into larger constructs. So why is it
that many of these debates center around macros, which is another
paradigm that bundles functions and data into larger constructs?
Both objects and macros have IMO similar potential for abuse and
obfuscation.

But to answer your question, I use a macro when I have a problem
that can't be easily reduced to a naive function. I also use object
classes when I have a problem that can't be easily reduced to a
simple data type. When I don't need an macro or an object class, I
just use naive functions and simple data types.
Dec 9 '06 #169
mystilleef wrote:
>
People only contribute to things they understand and appreciate. More
people would be writing Lisp libraries if it was worthwhile.
Apparently, it doesn't seem to be. A few years ago, I tried to write an
editor is Scheme. The experience was appalling. I was able to write a
fully functional prototype editor in less than a week in Python.
Shockingly, at the time, I had no experience in Python. Guess which
community I was inclined to contribute to afterwards. I hear stories
similar to mine time and again, yet the Lisp community won't take heed.
They'd rather squeal about the superiority of macros and whine about
their frustrations in Python news groups.
Hmm.. Here is my first prototype in Lisp. It took 20 seconds
to write.

(defun display-editor ()
(capi:contain (make-instance 'capi:editor-pane)))

CL-USER 1 (display-editor)
#<CAPI:EDITOR-PANE 2069F40C>

CL-USER 2 >
W

Dec 9 '06 #170

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

Similar topics

14
2181
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
8839
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9584
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
9398
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
9345
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,...
1
6811
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
6081
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
4894
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3327
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
2809
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.