Python vs. Lisp -- please explain

A

Alexander Schmolck

Michele Simionato said:
I replied to this message yesterday, but it did not appear, so let's
try again.

I agree with your points, but I would not say that Lisp is
intrinsically more dynamic than Python as a language;

Neither would I -- I don't think either is obviously more dynamic than the
other.

But since it has been implied that python's comparatively poor performance is
simply due to it being more dynamic than other languages, I wanted to point
out that one could with just as much justification claim CL to be more dynamic
than python (it is in some regards, but not in others -- how to weight them to
achieve some overall "score" is not obvious. I really doubt that python will
ever come remotely close to the level of dynamism that now defunct lispmachine
technology achieved, though).
it is just more interactive and has more features (and more complexities
too).

Indeed -- CL is much more complex than python and has many, many more warts.

As for common lisp being "just more interactive" -- all things being equal I
fail to see how "more interactive" cannot imply more dynamic -- IMO it doesn't
get much more dynamic than changing and inspecting things interactively. Also
not all the ways in which CL is more dynamic represent features that increase
complexity. For example in CL you could just write

def foo(x, l=[], N=len(l)): [...]

and have it work as expected because defaults are evaluated on call (this is
one of the very rare occassions of an obvious design wart in python, IMO).

In other cases, of course, more dynamism seems to involve added complexity.
For example CL has sane (dynamically scoped) global variables (and local ones,
if you declare them "special"). I think python is somewhat broken in this
regard, but I must admit I have no idea how to implement dynamically scoped
variables simply and "pythonically", so I wouldn't call it an obvious design
flaw.
BTW, regarding your first point on interactive sessions, are you aware
of Michael Hudson's recipe
"automatically upgrade class instances on reload()"
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/160164 ?

Thanks, it's nice to be aware of other solutions, I'll have a closer look at
some point. I've of course also written my own code for that purpose -- apart
from ipython.el and a couple of private utilities I even got sufficiently
pissed off by bugs introduced by python's poor support for serious interactive
work that I started writing some sort of versioned module system that kept
track of what was being imported from where to where, but I ran out of time
and ultimately for this and unrelated reasons switched to matlab in this
particular case.

Matlab sucks in countless ways, but it gives a superior interactive
environment. If you do experimental work where state is expensive to recompute
from scratch but where you need to tune various parameters to obtain the
desired results, problems introduced by changes not properly propagating are
very, very irritating -- especially if you want to keep a record of what changes
effected what, so that your experiments are repeatable.

'as
 
D

Dennis Lee Bieber

This isn't a rhetorical question. In the mid-80s, Apple and Texas
Instruments collaborated on a Macintosh II computer with a Lisp
coprocessor. The problem was, according to benchmarks at the time, Lisp
compiled and run natively on the coprocessor was actually slower than Lisp
interpreted on a standard Macintosh II.
You'd think TI would have learned from the TI99/4... The cartridge
BASIC interpreter for that machine was, itself, interpreted by the
native "language".
--
 
?

=?iso-8859-1?q?Luis_M._Gonz=E1lez?=

Carl said:
Paul Rubin wrote:
Well. "... the PyPy team works on ..." is definitively much too strong.
It is more like "... the PyPy team is thinking about ...". It is very
unclear whether it will work on a technical level and whether the EU
will allow us to allocate resources accordingly.

In this thread
http://groups.google.com/group/comp.lang.python/msg/5132f0d48c9e7be9
Christian Tismer said that he would work on this, even if this is not
pursued by the Pypy team, because he has personal reasons for doing it.

So I'm confident that sooner or later, it will be possible to create
extension modules written in Rpython.
 
R

Rocco Moretti

Alexander said:
I wanted to point
out that one could with just as much justification claim CL to be more dynamic
than python (it is in some regards, but not in others -- how to weight them to
achieve some overall "score" is not obvious.

I think it's worth pointing out that not all dynamicism is equal, when
it comes to difficulty in compiling to machine code.
For example in CL you could just write

def foo(x, l=[], N=len(l)): [...]

Although computing default arguments at call-time vs. define-time is
arguably more dynamic, it really doesn't (appreciably) increase the
difficulty in creating machine code.

I think (see Caveat) that the one major difference between Lisp and
Python that has a major bearing on compilability is mutability.

Lisp, like the good functional language that it is, has (primarily)
immutable values, and minimal side effects. That is, you can make a
function that takes in one value, and outputs a different value, but
once you have a handle on a value, that value doesn't ever change. That
makes it comparatively easy to track value paths, and assign proper
machine code to each operation.

Python, on the other hand, is mutable to an absurd degree, with
reassignments and side effects galore. Even a relatively simple function
like:

def f():
act(module.value)
random_function()
act(module.value)

can't be (automatically) replaced with the "obvious" equivalent:

def f():
mv = module.value
act(mv)
random_function()
act(mv)

because of the off chance that random_function() will reassign
module.value. Even if you look at random_function(), and rule out a
change to module.value, there is always a chance that a some other
thread will alter module.value in the mean time. Trivial example, true,
but when you figure that you can do the same to any operation or builtin
function, the compiler is never quite sure what a particular function
will do, what side effects it may have, or what type it will return. In
order to be ready for any contingency, a compiled Python program will
effectively have to incorporate the entire interpreter.

C/C++ gets around the mutability issue by straight-jacketing types &
functions. A variable will only contain a particular type (or a
subclass), and a function always has a particular signature.

Granted, there are ways of doing heavy duty code analysis, and pinning
down functions, types, and side effects in Python, and
Psyco/PyPy/ShedSkin are making good strides in that regards. But due to
the heavy dependency on mutable objects and side effects in Python, such
analysis will never be as easy as with Lisp, and considering Python has
had less time, and less investment in those areas, it's no wonder that
it's only just now seeing progress on the compiler front.


* Caveat: I've never seriously programmed in Lisp, and the last time I
looked at it was some time ago, with not-up-to-date reference materials.
I might be mistaken about the extent of mutability in current versions
of Lisp. Hopefully others with more knowledge can give more accurate
details of mutability/side effects in Lisp vis-a-vis ease of compilation.
 
I

Isaac Gouy

Steven said:
[snip for brevity]
Sure, all this is true, except for the term "interpreter."
You would surely not use the word that way, unless you
just didn't want to communicate.

Do you honestly believe that the CPU doesn't have to interpret the machine
code, or are you just deliberately playing silly buggers with language?

In modern CPUs, there is an intermediate layer of micro-code between the
machine code your C compiler generates and the actual instructions
executed in hardware. But even if we limit ourselves to obsolete hardware
without micro-code, I ask you think about what an interpreter does, and
what the CPU does, in the most general way possible.

Both take a stream of instructions. Both have to take each instruction,
and execute it. In both cases the link between the instruction and the
effect is indirect: for example, the machine code 00000101 on the
Zilog Z80 processor causes the CPU to decrement the B processor register.
In assembly language this would be written as DEC B. There is absolutely
nothing fundamental about the byte value 5 that inherently means
"decrement B processor register".

In other words, machine language is a language, just like it says, and
like all languages, it must be interpreted.
Your paragraph above that starts with "No of course not",
even omits a point that everyone understands, you can in
fact expect a .py file will work independent of machine
architecture - like any interpreted language.

Amazing. In your previous post you were telling everybody how the
*disadvantage* of interpreted programs is that they won't run unless the
interpreter is present, and in this post you are telling us that
interpreted languages will just work. What happened to the requirement for
an interpreter?

Let's see you run that Python program on a Zilog Z80 without a Python
interpreter. Can't be done. No interpreter, whether in hardware or
software, and the program won't run, whether in source code or byte code
or machine code.

If I allow that the machines have an interpreter, perhaps you'll return
the favour and install an interpreter for machine language (often called
an emulator). Now your compiled C or Lisp code also will run independent
of machine architecture.

In order to force "interpreted language" and "compiled language" into two
distinct categories, rather than just two overlapping extremes of a single
unified category, you have to ignore reality. You ignore interpreted
languages that are compiled, you ignore the reality of how machine code is
used in the CPU, you ignore the existence of emulators, and you ignore
virtual machines.

We all know
what native code compilation buys you and what it doesn't.

Did you fail to learn *anything* from my parable of interpreted Lisp on a
Macintosh II running faster than compiled Lisp running on a Mac II fitted
with a Lisp processor?

A different perspective:

"Although we refer to Lua as an interpreted language, Lua always
precompiles source code to an intermediate form before running it.
(This is not a big deal: Most interpreted languages do the same.) The
presence of a compilation phase may sound out of place in an
interpreted language like Lua. However, the distinguishing feature of
interpreted languages is not that they are not compiled, but that any
eventual compiler is part of the language runtime and that, therefore,
it is possible (and easy) to execute code generated on the fly. We may
say that the presence of a function like dofile is what allows Lua to
be called an interpreted language."

p57 Programming in Lua
 
A

Alexander Schmolck

Rocco Moretti said:
I think it's worth pointing out that not all dynamicism is equal, when it
comes to difficulty in compiling to machine code.

No kidding (do you have any idea how this thread started out?).
Lisp, like the good functional language that it is, has (primarily) immutable
values, and minimal side effects.
[further nonsense snipped]

Please don't spread misinformation about things about which you are clueless[1].

'as


Footnotes:
[1] Just as a minor illustrative detail: in python 2 out of 4 builtin
collection types are immutable (tuples and strings; newer versions also
have immutable and mutable sets) in CL 5 out of 5 are mutable
(arrays/vectors/strings, hash-tables, cons cells).
 
K

Kay Schluehr

Paul said:
I've wondered that as well.


But does that make it "proper Python"? Having, for example, only one
type associated with a name (they use the term "variable", though) at
any given time makes it more like various statically typed or
functional languages, although I can fully understand why you'd want
this restriction.

Paul

I would say yes, it is still "proper Python" in that each RPython
program is also a CPython program. That does not tell us much though,
because a simple calculator providing basic arithmetic operations in
infix notation fits the definition as well. The reason why RPython is
not formally defined may be that it is dedicated to be a maximal
sublanguage of Python that can be accepted by a reasonable
type-inferencer that translates code into a statically typed language.
I find this idea fascinating. Extending the type system by structural
types ( e.g. duck-typing a la C++ ) or algebraic types ( ML -like type
constructors including recursive types ) is a declarative way to extend
the languages power. Another one is extremely-late-binding enabling
arbitrary mutability. Now think for a moment about Guidos idea of
optional type annotations. How would this fit into the whole picture?

Kay
 
R

Roy Smith

Many people in this thread have said things like:
Interpreted? Compiled? Scripting language?

Let me quote from the preface to "Programming Ruby: The Pragmatic
Programmer's Guide" by David Thomas and Andrew Hunt (aka "the pickaxe
book").

----------
In the old days, the distinction between languages was simple: they were
either compiled, like C or Fortran, or interpreted, like BASIC. Compiled
languages gave you speed and low-level access; interpreted languages were
higher-level but slower.

Times change, and things aren't that simple anymore. Some language
designers have taken to calling their creations "scripting languages." By
this, we guess they mean that their languages are interpreted and can be
used to replace batch files and shell scripts, orchestrating the behavior
of other programs and the underlying operating system. Perl, TCL, and
Python have all been called scripting languages.

What exactly *is* a scripting language? Frankly we don't know if it's a
distinction worth making.
----------

I've made several attempts to sound intelligent in this thread, and each
time, I bailed out before hitting the Post button. I keep coming back to
the conclusion that Thomas and Hunt said it better than I possibly could.

BTW, if like Python and haven't looked at Ruby, it's worth a glance. If
Python can be called similar to Lisp, then Ruby is even more so. I'm not
fond of Ruby's perlesqe syntax, but I like many of the fundamental ideas.
 
I

igouy

Donn said:
For me that would be partly because I don't know that
much about Java, honestly. Just searching at random
for something about the subject, I cam across this -
http://www-128.ibm.com/developerworks/java/library/j-native.html?loc=j
- which seems like it might be of some interest here.

My impression from reading this is that Java actually
can be compiled to native code, though in 2002 this
was relatively new.

Donn Cave, (e-mail address removed)


Excelsior Jet ahead-of-time (AOT) compiler FAQ
"How does it work from the technical point of view?"
http://www.excelsior-usa.com/jetfaq.html#internals
 
P

Peter Mayne

Torsten said:
It's byte-compiled for a VM, that's not the same, and you know it.

Do you mean that Python is byte-compiled for a VM, and not Java, or
vice-versa?
I agree that the distinction between interpreted and compiled
languages is not as clear as between positiv and negative numbers,
however, neither anybody has claimed that so far, nor it is
necessary. It must be *practical*, i.e. a useful rule of thumb for
decision making. If you really know all implications (pros and
cons) of interpreted languages, it's are very useful rule in my
opinion.

So what kind of practical decisions are you trying to make? What kind of
implications are useful to you?

PJDM
 
P

Paul Boddie

Kay said:
I would say yes, it is still "proper Python" in that each RPython
program is also a CPython program.

I suppose it depends on which direction you're coming from, in that
many Python programs just wouldn't be able to run in RPython. But then
I can understand the convenience of having a subset of Python that is
executable by CPython, but which can also be inspected and processed
for other purposes, and whose programs maintain their semantics in both
situations.

Paul
 
T

Torsten Bronger

Hallöchen!

Paul Boddie said:
I suppose it depends on which direction you're coming from, in
that many Python programs just wouldn't be able to run in
RPython. But then I can understand the convenience of having a
subset of Python that is executable by CPython, but which can also
be inspected and processed for other purposes, and whose programs
maintain their semantics in both situations.

I'm still afraid of the following scenario: Eventually, people might
regard "RPython plus type declarations" (or something similar) as
first-class Python because it's faster and runs on more
implementations, so they try to stick to it. So effectively you
would have changed Python.

Maybe I misunderstood something because I could not follow all of
Kay's text but I think one should not change Python or create a
look-alike to allow for better implementations. The language should
fit my brain rather than an implementation.

Tschö,
Torsten.
 
P

Paul Boddie

Alexander said:
No kidding (do you have any idea how this thread started out?).

I had to remind myself.
Lisp, like the good functional language that it is, has (primarily) immutable
values, and minimal side effects.
[further nonsense snipped]

Please don't spread misinformation about things about which you are clueless[1].

I don't see why you have to be quite so blunt, here. Anyway, some of
the observations made about Python, especially when any comparisons
with Lisp (once corrected) show that Python is more similar to Lisp
than previously thought, are worth considering with respect to things
like type inference and the subsequent generation of low-level code.
Footnotes:
[1] Just as a minor illustrative detail: in python 2 out of 4 builtin
collection types are immutable (tuples and strings; newer versions also
have immutable and mutable sets) in CL 5 out of 5 are mutable
(arrays/vectors/strings, hash-tables, cons cells).

Well, apart from a brief encounter with Lisp back in the microcomputer
era, I've only just got back into looking at the language, and I
suppose I'll eventually find out how the optional type declarations
mentioned occasionally in connection with Lisp actually manage to
handle the harder problems around efficient code generation. I haven't
really studied type systems or compilers in any depth, however, but
having considered the issues for a while I'd like to think that my
rating has progressed from "clueless" to "mostly clueless" by this
point.

Paul
 
E

Ed Jensen

Roy Smith said:
BTW, if like Python and haven't looked at Ruby, it's worth a glance. If
Python can be called similar to Lisp, then Ruby is even more so. I'm not
fond of Ruby's perlesqe syntax, but I like many of the fundamental ideas.

I can't get over Ruby's ugly syntax. :(

Long live Python! :)
 
D

dlp

Paul said:
I think both of you are missing the point of the question, which is
that Lisp is dynamically typed exactly the way Python is and maps to
Python almost directly; yet good Lisp implementations are much faster
than CPython.

But Lisp isn't dynamically typed "exactly the way Python is". Python
documents ways to manipulate the internals of objects at runtime. It
is
possible to add, change or delete methods and slots by directly
changing
the hashtable they're stored in. While CLOS does permit a certain
amount
of runtime redefinition, it is not as completely free wheeling and
unpredicatable.
 
P

Paul Rubin

But Lisp isn't dynamically typed "exactly the way Python is".
Python documents ways to manipulate the internals of objects at
runtime. It is possible to add, change or delete methods and slots
by directly changing the hashtable they're stored in. While CLOS
does permit a certain amount of runtime redefinition, it is not as
completely free wheeling and unpredicatable.

Although CLOS is now part of the Lisp standard I haven't generally
thought of it as describing the language semantics. It's more like a
library routine. Python's standard library generally doesn't provide
documented ways of mucking around with the internal structure of
library classes. CLOS (or something close to it) similarly can and
has been implemented as a Lisp macro package independent from the rest
of the Lisp system.
 
T

Torsten Bronger

Hallöchen!

Peter Mayne said:
Do you mean that Python is byte-compiled for a VM, and not Java,
or vice-versa?

I mean "Python is byte-compiled for a VM".
So what kind of practical decisions are you trying to make?

Which language should I use for my project.
What kind of implications are useful to you?

Speed, ease of programming, necessity to learn/use a secondary
language, issues with distributing, portability.

Tschö,
Torsten.
 
P

Paul Boddie

Torsten said:
Speed, ease of programming, necessity to learn/use a secondary
language, issues with distributing, portability.

Indeed. Given the various convenient arguments about what "interpreted"
means (and how Python is simultaneously the same as and yet quite
different to Lisp), you'd think that the average C/C++/Lisp programmer
would have to be quite familiar with microcode to finish off a fair
number of their projects.

Paul
 
K

Kay Schluehr

Torsten said:
Hallöchen!



I'm still afraid of the following scenario: Eventually, people might
regard "RPython plus type declarations" (or something similar) as
first-class Python because it's faster and runs on more
implementations, so they try to stick to it. So effectively you
would have changed Python.

I wonder why you believe that it would run on more platforms? This
assertion is justifiable with regard of tiny target hardware - but
else? I do think that "RPython++" could be a viable replacement for C
as a systems programming language BECAUSE it is connected closely to
Python. It is a kind of upside-down evolution: a low level language
emerges from a more high level language. We currently know only the
other side of the story. RPython would just be the common denominator
or the language interface. Gilad Bracha suggested optional type systems
for dynamic languages[1] but as it seems to me RPython would be a fine
candidate for a declarative layer, not Python.
Maybe I misunderstood something because I could not follow all of
Kay's text but I think one should not change Python or create a
look-alike to allow for better implementations. The language should
fit my brain rather than an implementation.

It should first of all fit the diversity of a programmers needs. C was
never considered as a hostile brother of Python so why should it be
Pythons own son?

Kay
 

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

Forum statistics

Threads
473,780
Messages
2,569,610
Members
45,255
Latest member
TopCryptoTwitterChannels

Latest Threads

Top