What's better about Ruby than Python?

  • Thread starter Brandon J. Van Every
  • Start date
J

John J. Lee

(e-mail address removed) (A. Lloyd Flanagan) writes:

[...]
Don't get me wrong: you can do great things with C++ if you're an
expert. Problem is, if you're not, you can do tremendous damage.

While I take Alex's point about the practicalities of getting people
to use a language (independent of it's actual appropriateness for the
job at hand), I just suspect there must be a better language out there
in the multiverse, which did the job of integrating nicely with C,
allowing incremental improvement of C code *without* actually trying
to *be* C (+more stuff on top). Of course, it's far too late now.


John
 
D

Dave Kuhlman

Andrew Dalke wrote:

[snip]
The complaint about macros has been their tendency to
increase a single person's abilities at the cost of overall
loss in group understanding. I've heard references to
projects where that didn't occur, but am not swayed
by it because those seem staffed by people with
extraordinarily good programming skills almost never
found amoung the chemists and biologists I work with.

I just took a quick look at the "Revised5 Report on the
Algorithmic Language Scheme". Macros in Scheme5 are called
"hygienic macros", so apparently there are some dirty macros that
we should worry about. My understanding is that macros came to
Scheme slowly, with resistence, with a good deal of thought, and
with restrictions.

"More recently, Scheme became the first programming language
to support hygienic macros, which permit the syntax of a
block-structured language to be extended in a consistent and
reliable manner."

See:

http://www.schemers.org/Documents/Standards/R5RS/HTML/

http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-3.html

http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-7.html#%_sec_4.3

I have the same worry that some others on this thread have
expressed, that a macro capability in Python would enable others
to write code that I would not be able to read or to figure out.

[snip]

Dave
 
K

Kenny Tilton

Dave said:
Andrew Dalke wrote:

[snip]
The complaint about macros has been their tendency to
increase a single person's abilities at the cost of overall
loss in group understanding. I've heard references to
projects where that didn't occur, but am not swayed
by it because those seem staffed by people with
extraordinarily good programming skills almost never
found amoung the chemists and biologists I work with.


I just took a quick look at the "Revised5 Report on the
Algorithmic Language Scheme". Macros in Scheme5 are called
"hygienic macros", so apparently there are some dirty macros that
we should worry about.

(defmacro whoops (place &body code)
`(let ((x (random 3)))
(setf ,place (progn ,@code))))

....wreaks havoc if the code refers to an X it had bound to something
else and expected it to be used. otoh:

(defmacro c? (&body code)
`(lambda (self) ,@code))

....is cool because I can do the anaphoric thing and provide the user
with a uniform referent to the instance owning the slot, ala SmallTalk
or C++ with "this".


My understanding is that macros came to
Scheme slowly, with resistence, with a good deal of thought, and
with restrictions.

"More recently, Scheme became the first programming language
to support hygienic macros, which permit the syntax of a
block-structured language to be extended in a consistent and
reliable manner."

See:

http://www.schemers.org/Documents/Standards/R5RS/HTML/

http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-3.html

http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-7.html#%_sec_4.3

I have the same worry that some others on this thread have
expressed, that a macro capability in Python would enable others
to write code that I would not be able to read or to figure out.

Do what I do. Don't look at anyone else's code (if you have to work on
it, rewrite it anyway) and never show your code to anyone.

Naw, c'mon, everyone seems to be conceding macros are powerful. But you
are going to be held back by fear and worry? Well, I am a lispnik, we
always opt for power and damn the torpedos, as when we go for the
productivity win of untyped variables and give up on bugs strong static
typing is supposed to find.



--

kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
-- Bob Uecker
 
O

Olivier Drolet

Andrew Dalke said:
Olivier Drolet:

Err, it was me, no?

Sorry for the confusion. As a neophite news poster, I got mixed up
with names. Alex Martelli's arguments really got my attention and his
name stuck. Especially his argument regarding linguistic divergence.
Sigh.

(...)
Following Aahz's suggestion -- what would a Python-with-macros
look like?

I presume Aahz' suggestion is "readability". Thats indeed tricky.
Macros can only work consistently in Common Lisp because of
parentheses, but I don't know ennough about the reliability of
Python's delimitors. Dylan macros, for example, are said to differ in
power and flexibility from those of CL, so I'm led to understand. It
must be said that parens in Common Lisp are also essential in ensuring
the ability of a program alter itself or another program. Whence the
notion of Lisp as a "programmable programming language". (This isn't
to say that this is impossible in other programming languages, only
perhaps a bit trickier.)

Common Lisp macros can often significantly improve code readability by
merely reducing the amount of code. This is seen as a desirable
tradeoff, especially in large projects. If code readability is
paramount within the Python community, does the latter generally shy
away from projects in which code complexity is likely to increase
dramatically, i.e. where readability is likely to suffer?

I ask this only because of the fierce opposition the idea of macros
has been receiving here. Linguistic divergence seems to be seen as
leading inexhorably towards a degradation in code readability.

At the end of the day, I understand and respect a community's choice.
I'm in agreement with the view that languages are molded by their
community, and inversely so. The relation between the language, its
practitionners and the problem spaces being addressed is a dynamic
one. In the end, what ever works for the Python community is fine,
even rejecting macros for the sake of readability.


Olivier
 
T

Terry Reedy

Dave Kuhlman said:
See:

http://www.schemers.org/Documents/Standards/R5RS/HTML/

http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-3.html
http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-7.html#%_sec_4.3

I have the same worry that some others on this thread have
expressed, that a macro capability in Python would enable others
to write code that I would not be able to read or to figure out.

According to the second referenced page ("Background"), not a
completely baseless worry, although the Scheme divergence may have had
nothing to do with macros:

"The first description of Scheme was written in 1975...
Three distinct projects began in 1981 and 1982 to use variants of
Scheme for courses at MIT, Yale, and Indiana University [21, 17,
10]...
As Scheme became more widespread, local dialects began to diverge
until students and researchers occasionally found it difficult to
understand code written at other sites. Fifteen representatives of the
major implementations of Scheme therefore met in October 1984 to work
toward a better and more widely accepted standard for Scheme.
"

Reading the third referenced page on Macros, I notice that the amount
of syntax definition for the macro sublanguage is as large as a
substantial portion (one-third?) of that for core Python (if condensed
to the same density). So, just by definitional bulk, having it in the
language would not be a free ride.

Terry J. Reedy
 
R

Roy Smith

Common Lisp macros can often significantly improve code readability by
merely reducing the amount of code.

If what you're talking about is basicly refactoring, then it seems like
you could get the same code reduction by defining new functions/methods.
What does a macro give you that a function doesn't?

In C, the answer was "faster code", which I claim is simple a non-issue
for Python (we're not after speed in the same way C guys are).

In C++ the answer seems to be "generic programming", in the sense that
templates let you factor out the data type from the algorithm. Again, a
non-issue in a dynamic language like Python, where type information is
carried in the object, not the container.

So, is there something else that macros buy you that I'm not seeing?
People keep talking about how lisp macros are nothing like C/C++ macros.
OK, I'm willing to be educated. How are they different? Can somebody
give an example? Keep in mind that the last time I did any serious lisp
was about 20 years ago.
 
R

Roy Smith

Juha Autero said:
I think the problem here is same as with understanding Python
variables and assignment. People think names as objects themself
rather than bindings to an object. (Maybe I should have said "things"
to avoid confusin. Though in Python, everything you can bind a name to
is a Python object.) They think that after

class foo: pass

you get

+-----+
| foo |
+-----+

but in Python in reality you get
+-----+
foo --> | |
+-----+

So, in Python all objects are basically anonymous. They just have
names bound to them. And since everything is an object, this goes for
classes and functions, too. I'm not sure about modules though.

Well, classes (and modules) are not really anonymous. A class knows
it's name (as does a module).

so, a more accurate picture would be
+-----+
foo --> | foo |
+-----+
 
A

Andrew Dalke

Kenny Tilton:
as when we go for the
productivity win of untyped variables and give up on bugs strong static
typing is supposed to find.

You do realize that strong typing and static typing are different
things?

What does (the lisp equivalent of) 2.5 + "a" do?

In Python, a strongly typed language, it raises an exception. I
consider that a good thing.

But Python is not statically typed.

Andrew
(e-mail address removed)
 
A

Andrew Dalke

Kenny Tilton:
Lisp is sick. From the hyperspec on make-hash-table, the test for
lookups can be "eq, eql, equal, or equalp. The default is eql." EQUAL
would work for this case. EQL just looks at object identity.

Given the mutability in the structure, how is the hash key generated?
No, to match the power of my code you need to do:

(let ((b (make-instance 'box
:left 10
:right (c? (* 2 (left self)))))
(print (list (left b) (right b)))

Again, I don't know enough Lisp to follow what you are saying.
Download Paul Graham's On Lisp, he has a macro in there that hides all
the plumbing you used for cacheing. :) Look for "Memoize".

As I pointed elsewhere, I tried a couple times to learn Lisp,
if only to figure out how to tweak Emacs. I never succeeded.
Perhaps for the same reason I never liked HP's stack oriented
calculators? And yes, Dylan's another language on my 'should
learn more about' because of its in-fix approach to Lisp-style
programming.
The bestest I could do without macros would be:

(make-instance 'box
:left (c? (lambda (self)
(+ 2 (right a)))
....

Which implies Python's object model and Lisps are different,
because my code requires but one change per method, just
like your macro solution. While macros would be better
for this example, for Lisp, it isn't a good example of why a
macro system would improve Python's expressability.
The anti-macronistas are better off with the argument, hey, if you want
Lisp, use Lisp. Let's keep it simple here. the question for you all is
how far you want to take Python.

But that statement expresses a certain arrogance which grates
against at least my ears. The point I've made over and over is
that languages which optimize for a single person do not
necessarily optimize for a group of people, especially one
which is scattered around the world and over years. Given
that latter definition, Python is extraordinary advanced, even
further than Lisp is.

For observational evidence of this, I suggest my own
subfields, computational biology and computational chemisty.
In the first there are bioperl, biopython, biojava, and bioruby,
all with active participants and a yearly confererence organized
by open-bio.org. But there is only a rudimentary biolisp project
with minimal code available and just about no community
involvement. In the latter, Python takes the lead by far over
any language other than C/C++/Fortran with commercial support
for a couple toolkits and several more free ones beyond that.
There's even a workshop in a couple weeks on the representation
of biomolecules for Python. There are also some Java and C++
toolkits for chemical informatics. And again, there is no Lisp
involvement.

I ask you why. And I assert that it's because Lisp as a
language does not encourage the sort of code sharing that
the languages I mentioned above do. So while it is very
expressive for a single person, a single person can only
do so much.

Andrew
(e-mail address removed)
 
J

Jacek Generowicz

Andrew Dalke said:
Kenny Tilton:

You do realize that strong typing and static typing are different
things?

Note that Kenny said "untyped _variables_" not "untyped objects" or
"untyped language".
What does (the lisp equivalent of) 2.5 + "a" do?

Common Lisp complains that "a" is not a number.
In Python, a strongly typed language, it raises an exception.

Common Lisp is strongly and dynamically typed, just like Python
.... although CL does allow type declarations, for optimization
purposes.
 
M

Mario S. Mommer

Andrew Dalke said:
As I pointed elsewhere, I tried a couple times to learn Lisp,
if only to figure out how to tweak Emacs. I never succeeded.
Perhaps for the same reason I never liked HP's stack oriented
calculators?

Lisp is simple.

(<operator> <item-1> <item-2> ...)

Where's the problem?

Granted, you need an editor that helps you to match the parens (which
is nothing particularly esoteric), but other than that, it is just a
normal programming language. You've got functions, variables, loops,
etc. even goto, (and macros, and code generation/manipulation
facilities you have not seen nor will see anywhere else, but you do
not need to use them for simple stuff). What was it that you couldn't
understand?
For observational evidence of this, I suggest my own
subfields, computational biology and computational chemisty.
In the first there are bioperl, biopython, biojava, and bioruby,
all with active participants and a yearly confererence organized
by open-bio.org. But there is only a rudimentary biolisp project
with minimal code available and just about no community
involvement. In the latter, Python takes the lead by far over
any language other than C/C++/Fortran with commercial support
for a couple toolkits and several more free ones beyond that.
There's even a workshop in a couple weeks on the representation
of biomolecules for Python. There are also some Java and C++
toolkits for chemical informatics. And again, there is no Lisp
involvement.

I ask you why.

You shouldn't confuse success with quality. For experimental evidence
look at music charts. On the other hand, if people feel more
confortable with python, then so be it.

Lisp suffers also from historical problems. It was too big and too
slow for mid-80's up to mid-90's PCs, and there where far too many
incompatible dialects, which led to it falling in disgrace. But better
compilers, moores law, more memory, and an ANSI standard have improved
things up to a point where I think there is no reason not to use it.
And I assert that it's because Lisp as a language does not encourage
the sort of code sharing that the languages I mentioned above do.

This is ridiculous. You don't know Lisp so you do not have an idea
(hint: what you say is wrong), and thus you shouldn't be saying this.
So while it is very expressive for a single person, a single person
can only do so much.

People regularly work in teams on lisp projects. Is that just an
illusion of mine?
 
J

Jacek Generowicz

You wrote lots. Forgive me if I don't address everything. I wish I had
the time to address all your points more carefully.

Andrew Dalke said:
However, at present, the only example I've seen for when to use a
macro came from a method cache implementation that I could implement
in Python using the normal class behaviour,

Or using directors, or lexical closures. Similarly in Lisp, there is
more than one way to do it, and many would not choose the macro option
when implementing a memoizer.
so I don't have a good idea of when macros would be appropriate
*for* *Python*.

(Looks like you've found a need for them yourself - see later on.)

Well, frankly, in the context of Python, I find the whole discussion a
bit abstract. Lisp macros fundamentally rely on the fact that Lisp
programs are represented as lists, and that Lisp includes excellent
support for manipulating such lists. The consequence of this (source
code being a form of data) is that it is extremely easy to manipulate
Lisp source code within Lisp. You can already achieve similar things
in Python by typing your source code as a string, and performing
string manipulations on it, and then calling eval ... but it is many
orders of magnitude more painful to do it this way.

Alternatively, get your hands on the parse-tree (I believe there's a
module to help), and mess around with that. That should be much easier
that playing with strings, but still much more of a pain than Lisp
macros.
When this topic has come up before, others mentioned how
macros would theoretically be able to, say, modify list.sort
to return the sorted list after it has been modified in-place.

You don't need macros for that. With the advent of new-style classes,
you subclass list, override the sort function, and replace
__builtins__.list (maybe there's more to it, but as this is not
something I ever intend to do, forgive me for not checking the
details.)
Given the not infrequent request for the feature, I know that
if it was allowed, then some of my clients would have done
that, making it harder for me to know if what I'm looking at
is core Python behaviour or modified.

That's not the point of macros. The point is not to modify existing
behaviour behind one's back. The point is to add new behaviour
.... much like it is with functions, classes etc.
What you say is true, but most of the code I look at is
based on fundamental Python types, from which I can
be assured of fixed behaviour, or classes and functions,
where I can be assured that they are free to do their
own thing. The patterns of behaviour are fixed and
the opportunities for change well defined.

Macros, as I understand it, blurs those lines.

I don't think this has anything to do with macros. This is a
consequence of a language allowing to re-bind built-ins. I remind you
that Python allows this, today.
I will grant that Lisp or Scheme is the end-all and be-all of
languages.

:) Well, at least that's clear :) :)

[NB, I love Python, and wouldn't want to go without it, for a plethora
of reasons.]
Where's the language between those and Python?

I am not sure that there is a need for one; Python and Lisp are
already very close, as compared to other languages. But maybe some
interemediate language would serve a good purpose.
Is it possible to have a language which is more flexible than
Python but which doesn't encourage the various dialectization
historically evident in the Lisp/Scheme community?

Hmmm. I think this "dialectization of the Lisp/Scheme community" is a
bit like the "dialectization of the Algol Family community" or the
"dialectization of the functonal community" or the "dialectization of
the scripting (whatever that means) community"

The fundamental feature of Lisps is that they represent their source
code in a format which they themselves can manipulate easily. (Often
people try to characterize Lisps by the 4 or 5 fundamental operators
that you need to make all the rest, but I don't find this an
interesting perspective.) What's wrong with there being different
languages with this characteristic? What's wrong with there being
different functional languages? What's wrong with there being
different scripiting (whatever that means) languages ?

Maybe you refer to the fact that, should you wish to make a completely
new Lisp-like language, then starting with an already existing lisp,
and writing your first implementation in that (with the help of
macros), is usually by far the best way of going about it.

(This is exactly how Scheme was created, IIRC)

But your new language is exactly that. A new language. Faithful users
of the language in which you wrote that first implementation, will not
suddenly find that the language they know and love has been broken.
Could most macros also be written without macros, using
classes or lambdas?

Heh. You can write a lot of macros which don't need to be macros (so
don't). But there are some things for which macros are absolutely
necessary.

(Actually, in Lisp you could get by with functions and "'" (the quote)
.... but you'd still be writing macros, without official language
support for them.)

I guess that it boils down to delaying evaluation until you have had
the opportunity to manipulate your source.
How often are the benefits of macros
that much greater than classes&functions to merit their
inclusion.

Does it take skill to know when to use one over the other?

Often, it does. Some are no-brainers (Control structures, for example).
Do people use macros too often?

Some probably do. This is probably true of classes too.
When do they hinder misunderstanding?

When they are badly designed. This is true of classes too.
Are they more prone to misuse than classes&functions?

I guess it is generally true, that the more powerful and versatile the
tool, the more prone it is to misuse.
The complaint about macros has been their tendency to increase a
single person's abilities at the cost of overall loss in group
understanding.

No, no, NO, Noooooooooo ! :)

At the top of your reply, you agreed about my point that abstracting a
frequently repeated pattern is preferable re-implementing it all over
your code. _This_ is what macros are about.

One can write useless and obfuscating functions and classes, just like
one can write useless and obfuscating macros.
I've heard references to projects where that didn't occur, but am
not swayed by it because those seem staffed by people with
extraordinarily good programming skills almost never found amoung
the chemists and biologists I work with.

I do not advocate Lisp as a language for people who are not prepared
to invest serious time to understanding it, which probably includes
most people whose primary activity is not programming.

That is why I think Python is _extremely_ useful and necessary. It
provides a significant portion of the power of Lisp, for a small
initial investment.

I do not expect CERN physicists to use Lisp, I do expect them to use
Python.
The point I'm trying to make is that different, very smart people
like "Lisp", but insist on variations.

Very smart and not-so-smart people like "scripting languages", but
insist on variations. There's Perl, Python, Ruby ...
There is clisp

Clisp is just one implementation of an ANSI standardized Lisp (Common Lisp).
and elisp

Elisp is the scripting language of Emacs.

Now, Common Lisp is an all-purpose stand-alone language designed for
constructing complicated systems; Elisp is designed for configuning
and extending Emacs.

Complaining that this is "insisting on variations of lisp", and that
it is somehow a BAD THING, is a bit like complaining about the
co-existence of Python and Occam, as "insisting on variations of
languages with significant indentation".
As I understand it, macros can be used to make one lisp variation
act like another.

This is true to some extent. But just because it can be done, doesn't
mean that very many people actually ever want to do it. Yes, sometimes
CLers want to fake up a Scheme-like continuation, and the language
allows them to do it. Great. But that (pretending to be another
already existing language) is not the point of macros.
Did you really or are your making that up for the
sake of rhetoric?

Sorry, I should have made clear that I made it up for the sake of
rhetoric. However, the only thing that is untrue is the "A few days
ago" bit. It has happened repeatedly in the past.
If it takes more than four decades for different Lisp
implementations to agree on how to import a module, then I think
there's a problem.

Again, you are confusing "different implementations" with "different
languages".

Implementations of ANSI Common Lisp agree on, well, anything defined
within the standard.

Implementations of different languages clearly do not agree. This is
true of those in the Lisp family, just as it is for members of any
other family of Languages.
I needed to evalute a user-defined expression where the variable
names are computed based on calling an associated function. The
functions may take a long time to compute and most names are not
used in an expression, so I want to compute the names only when
used.

You want lazy evaluation ?
Did I start from scratch? No! I used Python to build the parse
tree

In Lisp, you start off with the parse tree. That's the great thing
about it.
then tweaked a few nodes of that tree to change the name lookup into
the right form, then generated the function from that parse tree.

You've just Greenspunned Lisp macros.

Manipulating the parse-tree is exactly what Lisp macros are about.
The syntax was the same as Python's, but the behaviour different.

In Lisp you would typically give a name to this behaviour, and then
you would be able to use it alongside the original language.

For example, if the user-defined expression is

(+ (foo 2) (bar a b c d))

The tweaked version would be

(lazy-eval (+ (foo 2) (bar a b c d)))

Writing a macro to make Lisp a uniformly lazy language (as you seem to
have been suggesting one might proceed, way up-post), is definitely
not the way to do it.
Though back at the Python level, it's a "call this function to get
the needed result",

In Lisp it's "call this macro to get the needed result".
and has precisely the same nature as any other Python function would
have.

And has percisely the same nature as any other Lisp macro would have.
And some languages are not-at-all close to Python. Eg, I wanted
to implement a domain-specific language called MCL

What, "Macintosh Common Lisp" ? :)
using my PyDaylight package. I ended up writing a parser for MCL
and converting the result into Python code, then exec'ing the Python
code.

In CL this is done with reader macros; a means of altering the way the
parse tree is constructed from the source data.
Similarly, SMILES is a language for describing molecules.
Why in the world would I want to extend Lisp/Perl/Python/
whatever to support that language directly?

a) Because it's easier to build it on top of Lisp than from scratch.

b) Because you never know what future requirements you might have.
??? Apparantly not Alan Greenspan.

Greenspun's Tenth Rule of Programming:

"Any sufficiently complicated C or Fortran program contains an
ad-hoc, informally-specified bug-ridden slow implementation of half
of Common Lisp."

(Of course, it's a general statement about developing in low-level
languages as compared to developing in higher-level ones.)
Please tell me how you would implement this language

load "abc.pdb" into a
select "resname LYS" from a into b
save b as "lysine.pdb"

as a macro in Lisp. I'll assume 'load-pdb' loads a PDB file into
a object which holds a set of atoms, and that object has the
method 'select-atoms' which creates a new (sub)set and also
has the method 'save-as' for saving those atoms in the right format.

And the above is all that the user can type.

How in the world does macros make handling that language
any easier than the standand parser-based non-macro solution?

I don't think I understand the true meaning of your question.


Anyway, your parse tree exapmle shows that you DO understand and use macros
.... you just don't know that that's the name of what you are doing :)
 
J

Jacek Generowicz

Hans Nowak said:
The problem is that a macro system that is too powerful can be harmful.

The problem is that a permissive language can be harmful.
Let's say you write a useful module. Python 3.6 just added a very
powerful macro system, and you use it to, say, write functions with
lazy evaluation, make strings mutable, and write your own flavor of
the for-loop. Now I cannot read your code anymore. A simple function
call, or a loop, does not mean what it used to mean.

Let's say you rebind all the attributes of __bulitins__. Now I cannot
read your code anymore (well, I can, but it doent'h do what it looks
like it will do).

If you deliberately want to break things, you don't need macros.

os.system("rm -rf *")

Just because a stupid or malicious programmer could do "bad things" is
not a reason to reduce a language's power. (You end up with Java.)
 
K

Kenny Tilton

Andrew said:
Kenny Tilton:


But that statement expresses a certain arrogance which grates
against at least my ears.

Really? I thought that was non-controversial or I would not have said
it. Earlier in this thread I thought I read a Pythonista saying, without
contradiction, that Python does not try to be everything. Lisp macros
try to be everything. ie, If Lisp does not have something I want, such
as C-style enums because I am literally translating a C RoboCup client
to Lisp, noproblemo, I just cobble one together, and I can arrange it so
the final syntax:

(enum CMD_KICK CMD_DASH (CMD_TEAR_OFF_SHIRT 42)...)

is close enough to C syntax that the C can be edited into Lisp by
changing/moving braces to parens, deleteing all the commas, and
hand-hacking the rare symbol=number usage.

The point I've made over and over is
that languages which optimize for a single person do not
necessarily optimize for a group of people, especially one
which is scattered around the world and over years. Given
that latter definition, Python is extraordinary advanced, even
further than Lisp is.

For observational evidence of this, I suggest my own
subfields, computational biology and computational chemisty.
In the first there are bioperl, biopython, biojava, and bioruby,
all with active participants and a yearly confererence organized
by open-bio.org.

You do not like? http://www.biolisp.org/

Give it time. It's a chicken-egg thing. In fact, my RoboCup project is a
conscious attempt to be the egg for a renaissance in RoboLisp. The
RoboCup server was originally a Lisp project, but teams are now almost
universally developed in Java or C++. The funny (and great for me!)
thing is that all those clients have to parse:

"(see 457 ((f l t 10) 12.3 23 2.3 5)..."

with parsers, where I just say: (read-from-string <msg>).

And I have already heard from one C or Java (they did not say) team that
is interested in my code base simply because it is Lisp.

We lispniks do look forward to the day when there is a larger Lisp
community, and we take great consolation from Python's success (and
Perl's and to a lesser degree Ruby's). That tells us there is great
unhappiness with Java and C++. It also shows that popularity and
dominance in computer languages may not be the advantage it seems to be
for OSes.

Lisp has been dead for twenty years, but some of us won't use anything
else (no macros!) and we even see a trickle of newbies on c.l.l., maybe
one a day. That is mighty small number compared to Python or Ruby, but
we used to see one a year. I got so curious I started a survey on cliki
(turns out Paul Graham gets a lot of credit):

http://www.cliki.net/The RtLS by Road

I was trying to find out how people ended up trying Lisp in spite of its
tiny community and death.
I ask you why.

Historical, for one. Lisp has always needed a meg or two of RAM. Even
when PCs had 8k, 64k, 128k... so C and Pascal became the languages of
the masses. Remember Pascal? <g> C++ was C trying to hop on the OO
bandwagon (don't get me wrong, I like OO) and Java hopped on the
internet bandwagon (and stayed close to C syntax to win those folks
over. Python wins because of its interactive qualty and seamless access
to C, and by adopting many cool ideas from more advanced languages--kind
of a best of both worlds.

Peter Norvig, a lisp biggy, has famously found Python to be equivalent
to Lisp (except for runtime speed, IIRC). Think of Lisp as compiled
Python. With macros and multi-methods etc etc. But you still have to
roll FFI binidngs to access C. I did that for my OPenGL project, using
macros which took slightly edited C headers and transformed them into
the FFI declarations.

The other thing Lisp did not have was cheap graphical workstations with
syntax-aware editors and optimizing compilers. So that got it off on the
wrong foot. But I look at it this way. Lisp already was a fad language
(when folks were all excited about AI) and has already died. But it is
still the language of choice for some very talented programmers who know
all about the other languages out there, andit is picking up a trickle
of interest. And when I look at languages like Perl and Python, I see
them adopting new features highly reminiscent of Lisp.

I ask you why? :)


--

kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
-- Bob Uecker
 
J

JCM

Heiko Wundram said:
Hmm... I still use <> exclusively for my code, and I wouldn't really
like it getting deprecated. At least for me, != is more difficult to see
when browsing source than <> is, as != has a striking similarity to ==,
at least at the first glance...
I know <> has been deprecated for long, but I'd much rather have both
syntaxes allowed, also for the future...

How about we keep them both, but make <> mean greater-than-or-less-than,
which is a different comparison than != on partially ordered sets.

1 > 2 -- false
1 < 2 -- true
1 != 2 -- true
1 <> 2 -- true

1 > 'x' -- false
1 < 'x' -- false
1 != 'x' -- true
1 <> 'x' -- false

Ok, I'm joking. Mostly.
 
J

Jacek Generowicz

Hans Nowak said:
Jacek Generowicz wrote:

[re-binding __builtins__ considered harmful]

I see your point. The obvious answer would be "so don't do that,
then". Of course, the same answer would apply to writing abusive
macros.
Exactly.

Python usually strikes a good balance between being permissive and
restrictive.

In your opinion. The opinions of others, as to where a "good balance"
lies, will be different. And that's just fine. That's why we have
different languages.

I happen to agree that Python strikes a good balance. I also think
that Common Lisp strikes a good balance. The position of "good
balance" is a function of the language's audeince.
You are right, but one could wonder if the drawbacks don't outweight
the benefits. Python is already powerful as it is (compared to
languages other than Lisp ;-). I'm not sure if powerful macros would
do much good.

Well, with an interactive language[*] you can easily get two types of
programmers: the providers, and the users. A good macro facility
allows the provider types to create very useful abstractions for the
user types. The user types can use those abstractions without having
the faintest clue that they are built using macros, and can happily
program in the language without ever writing one of their own. (A bit
like metaclasses.)

Just because there are macros or metaclasses in a language, does not
mean that everyone needs to know about them, while everyone can
benefit from them.

[*] I guess that this is not exclusive to interactive languages, but I
suspect it's more marked.

But, wrt macros in Python, I don't really see what Python macros would
look like. Lisp code is represented in a fundamental, hierarchical,
easily transformable built-in data type. This ain't true for Python.

Sometimes I think "if Python had Lisp-like macros, what I am trying to
achieve right now would be so much easier". This doesn't mean that I
would necessarily advocate the inclusion of macros in Python. What I
object to, is the suggestion (which has been made repeatedly around
the thread) that macros are evil and should be avoided, and that
macros are responsible for the fragmentation/death of Lisp.

Macros are great. If a good, Pythonic macro system could be invented,
I am sure that it could be put to great use, and that it would not
engender the death of Python. I am not sure that such a system can be
invented. I do not suggest that such a system _should_ be added to
Python.
 
A

Andrew Dalke

Kenny Tilton:
Jacek Generowicz:
Note that Kenny said "untyped _variables_" not "untyped objects" or
"untyped language".

Ahh, I hadn't caught that.

I did know Lisp had strong dynamic typing with optional static typing,
which was why I was surprised he mentioned it. I still don't understand
why he said it given that Python similarly meets the quoted statement.

Andrew
(e-mail address removed)
 
K

Kenny Tilton

Andrew said:
Kenny Tilton:


Jacek Generowicz:



Ahh, I hadn't caught that.

I did know Lisp had strong dynamic typing with optional static typing,
which was why I was surprised he mentioned it. I still don't understand
why he said it given that Python similarly meets the quoted statement.

?? I was just giving another example of how lisp errs on the side of
letting us shoot ourselves in the foot. I was not saying anything about
Python.

--

kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
-- Bob Uecker
 
A

Andrew Dalke

Mario S. Mommer:
Lisp is simple.

(<operator> <item-1> <item-2> ...)

Where's the problem?

Quantum mechanics is simple. It's just H | psi> = E | psi>

What's H mean? And psi? And bra-ket notation?

The reason my original forays into Lisp around 1990 failed was
because the documentation I had for learning it didn't talk about
anything I found interesting, like doing file I/O and graphics. It
went on-and-on about data structures and manipulating them.

My later attempts were by trying to customize my Emacs LISP
setup, and getting various errors because I didn't know the
quoting rules well enough.

Since then it's been limited to incidental learning, like seeing examples
and trying to figure them out. Eg, consider Gabriel's "Worse is
Better" essay. The section "Good Lisp Programming is Hard"
http://www.ai.mit.edu/docs/articles/good-news/subsubsection3.2.2.4.html
gives this example

(defun make-matrix (n m)
(let ((matrix ()))
(dotimes (i n matrix)
(push (make-list m) matrix))))

(defun add-matrix (m1 m2)
(let ((l1 (length m1))
(l2 (length m2)))
(let ((matrix (make-matrix l1 l2)))
(dotimes (i l1 matrix)
(dotimes (j l2)
(setf (nth i (nth j matrix))
(+ (nth i (nth j m1))
(nth i (nth j m2)))))))))

and says the above is both "absolutely beautiful, but it adds
matrices slowly. Therefore it is excellent prototype code and
lousy production code."

I've done a lot of matrix math, but even now cannot simply
look at the above code to figure out what it does, much less
does wrong. But I can figure them out from, say, Java,
in which I have no programming experience at all.

I've also looked at Lisp code when evaluating a package
written in Lisp. I was able to figure that library better than
the above, partially because I had already looked at 15 other
packages which did the same task, so knew the structure
of the solution. I turned out that the Lisp code was no more
powerful or flexible than the ones written in the other languages.
I didn't see good reasons to use Lisp for the problems in my
domain.
You shouldn't confuse success with quality. For experimental evidence
look at music charts. On the other hand, if people feel more
confortable with python, then so be it.

Quips are easy: "You shouldn't confuse power with quality."
This is ridiculous. You don't know Lisp so you do not have an idea
(hint: what you say is wrong), and thus you shouldn't be saying this.

Not being able to program in Lisp doesn't mean I don't know anything
about it. I've read the histories, the articles like Gabriel's, listened
to others as they talk about their experiences with Lisp, and decisions
to use an alternate language. I understand the decision to emphasize
its parse tree based approach over a more syntax oriented one. And
as you say, the semantics in Lisp are for the most part shared with
other languages.
People regularly work in teams on lisp projects. Is that just an
illusion of mine?

No. My take on things is that the people who do use Lisp these days
are self-selected for those who either 1) do things alone, ie, can and
will build everything from scratch, or 2) work hard at making sure
their code can be used by others. By "work hard" I mean smart
people willing to focus on the community and learn about the 7
or so different ways of saying 'equals' and the importants of closures
and all the other things needed to become good Lisp programmers.

The people I know focus mostly on developing new computational
techniques and only want to implement that part of the code, pulling
in code from elsewhere if possible. Hence, not #1 nor #2. (There
are some #1 projects, and the #2 people are almost invariable from
CS, learning Lisp first and biology second.)

In other words, the overlap between the types of people who are
good at programming in Lisp and those who decide upon a career
in computational life sciences is low.

Another possibilty I'm considering now is that the additional
flexibility that Lisp has, eg, for making frameworks, isn't needed
for the programming problems faced in this field, which for the
most part are either data munging or compute-bound algorithmics.
When then choose a more flexible language of a lesser one is
easier to learn and use? But a real Lisper would, I think, argue
that it means those tools are available for the few times it is needed.

Andrew
(e-mail address removed)
 
H

Hung Jung Lu

Alexander Schmolck said:
To recap: usually, if I change a class I'd like all pre-existing
instances to become updated ...... AFAIK doing this in a
general and painfree fashion is pretty much impossible in python

If I understand correctly what you want, then it is possible and
relatively painfree in Python. Please let me know if the following
snippet is ok.

#
# example of replacing a class in Python
#

import weakref

class InstanceAware:
dict = weakref.WeakValueDictionary()
def __init__(self):
self.__class__.dict[id(self)] = self
def __str__(self):
return 'Hello from %s class instance with id=%s' %
(self.__class__.__name__, id(self))

def replace_class(OldClass, NewClass):
olddict = OldClass.dict
newdict = NewClass.dict
for instance_id in olddict.keys():
instance = olddict[instance_id]
newdict[instance_id] = instance
instance.__class__ = NewClass
del OldClass

class A(InstanceAware):
dict = weakref.WeakValueDictionary()

class B(InstanceAware):
dict = weakref.WeakValueDictionary()

x = A()
y = A()
z = A()

print '--- Class A has %d instances' % len(A.dict)
print x
print y
print z

del z
replace_class(A, B)

print '--- Class B has %d instances' % len(B.dict)
print x
print y

output:

--- Class A has 3 instances
Hello from A class instance with id=12072832
Hello from A class instance with id=12177240
Hello from A class instance with id=15770208
--- Class B has 2 instances
Hello from B class instance with id=12072832
Hello from B class instance with id=12177240

regards,

Hung Jung
 

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,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top