[OPINION] - does language really matter if they all do the samething?
Paul Prescod
paul at prescod.net
Sat Jan 24 18:24:33 EST 2004
Dietrich Epp wrote:
> Please understand, before you read this, that I think Python is the most
> elegant language that looks and feels natural. My point is that there
> are plenty of programming techniques which aren't natural in Python, but
> are still useful.
I don't dispute this. Python is not the last and only programming
language. But your specific examples were not compelling. I would have
believed you if you'd said you do a bunch of logic programming and found
Prolog more comfortable. (but even in extreme cases like that I would be
tempted to see whether the task can be accomplished with a library or
mixin rather than a new language)
> Well, I don't mean that you absolutely can't capture a message, but it's
> just not something that's natural in Python the way it is in Objective
> C. In Objective C, I can create an object which doesn't respond to some
> message "foo". However, if I send "foo" to the object, it gets a chance
> to respond. In Python, there is no concept of messages. You would have
> to override the function that gets an object's attribute and create a
> function for it to return. You can capture function calls, but
> capturing method calls is a two-step process in Python which requires a
> little bit of magic to implement.
Programming languages are designed to turn processes that take N steps
into processes that take M steps. You seem to know enough Python to
trivially write a function that does the filtering necessary to capture
method calls. You can steal the code from the XML-RPC lib that is
already in the standard library.
> If I wanted to make this personal, I would accuse you of choosing your
> patterns to fit the language rather than vice versa.
I don't mean to be personal. But a lot of ex-Lisp programmers do not
feel the need to go back to Lisp to accomplish common tasks and a lot of
ex-Perl programmers use Python without going back to Perl. It's quite
possible that it is just a matter of preference. Some people would
rather go back to the language with the built-in feature and others
would rather extend Python with the feature they need. They are benefits
to both ways of doing it.
I tend to lean towards the integrating approach: it feels like more of a
"solution" to the problem than a workaround (i.e. once I've extended
Python it remains extended but if I switch languages then I have to keep
switching language the next time I have a similar problem). What if you
run into one of these problems in the middle of a ten thousand line
program? You have to figure out a way to exchange data between Python
and the other language, you have to distribute both interpreters, make
sure people on the team can read both languages, etc.
Of course there are (rare) circumstances where the other languages'
advantages are so extreme that it justifies the cost of integration,
distribution, training, etc.
>...
> Of course, you haven't seen my code, nor I yours. My most recent Perl
> script was about twenty lines of nothing but regular expressions and a
> couple dictionary operations. That would have been even less readable
> and writable in Python.
My experience is that the readability of regexp programs in Perl and
Python is roughly the same. I'll give a concrete example in a separate
email on Cameron Laird's thread.
> ... My Lisp project related to an RPG and random
> generation of items. It had lots of code like the following:
>
> (defun random-sword-magic-power (quality)
> (choose-random-assoc
> quality (poor medium good)
> ((5 0 0) (glows-in-the-dark))
> ((3 3 0) (magically-silent))
> ((1 5 1) (elemental-power (select-random '(earth water air fire))))
> ((0 2 4) (magical-keen-edge))
> ((0 0 2) (append (random-sword-magic-power 'medium)
> (random-sword-magic-power 'medium)))))
module game_symbols
class symbol: pass
water = symbol(water)
earth = symbol(earth)
poor = symbol(poor)
medium = symbol(medium)
good = symbol(good)
=======
from random import choice
from game_symbols import *
def choose_random_assoc(selector, properties):
# I can't find a defintion for this through Google
# So I presume you invented and implemented it yourself
value, options = selector
for key, value in properties.items():
... do something ...
function random_sword_magic_power(quality):
return choose_random_assoc(
selector = (quality, (poor, medium, good)),
properties = { (5, 0, 0): glows_in_the_dark(),
(3, 3, 0): magically_silent(),
(1, 5, 1): elemental_power(
choice([earth, water, air, fire])
(0, 2, 4): magical_keen_edge(),
(0, 0, 2): ????}
I don't follow what you are doing with the last line so I didn't
duplicate it.
So let's score this. I don't expect you to argue that the Python one is
some kind of stylistic slam-dunk. Personally I PREFER the variety of
syntax rather than using parens for everything. That's why I used a dict
instead of a tuple for the properties mapping. I used predeclared
symbols for things like "poor", "medium", "good" etc. so I'll get better
error messaging if I mistype them. (I could of course have used just
strings)
> The numbers on the left are probabilities relative to the other
> probabilities in the same column. So, when generating a random 'poor'
> magic quality of a sword, you have a 5/9 chance of getting 'glow in the
> dark'. For a 'good' quality, you have a 2/7 chance of getting two
> 'medium' qualities instead. It is difficult for me to imagine how one
> would go about making this function more concise, to me it looks
> downright minimal. The only thing I could see making it smaller would
> be removing the parentheses, but they would have to be replaced by
> something else such as commas or tabs.
The question isn't whether the Python could be massively better. That
would be moving the goal post. The question is whether the Lisp version
is different enough that a Python programmer should switch to Lisp for
this project. I wouldn't advise it myself.
> I'm not trying to say that all applications are like my application, and
> I'm not trying to say that my application can't be written in Python.
> I'm just saying that using macros, a paradigm that Python doesn't even
> come close to supporting, makes reading and writing functions like the
> above a lot easier. You don't even need to know that
> 'choose-random-assoc' is a macro, you just need to know how to use it.
> Heck, defun is a macro in Clisp.
I didn't know it was a macro and I don't know why it needs to be a macro
rather than a function. One argument could be performance. If so, I'd
plead no contest. A good reason to use other languages is performance. C
for memory manipulation performance. Perl for regexp performance. Lisp
and C++ for "do things at compile time rather than runtime" performance.
But as I understood the conversation we were talking about
expressiveness, not performance.
> I agree that functions are objects in Python. However, not everything
> in Python is an object. For example, names are not objects. In the
> above example, "foo.bar()", neither "foo" nor "bar" are objects, but
> they are references to objects. In some languages, such as C and Lisp,
> references to objects can be directly manipulated (Lisp has symbols, C
> has pointers).
Pointers are not at all analogous to Python names. C variables and
struct fields are analogous to Python names. Those can only be
manipulated by the C preprocessor.
>...
>
> In Python you have to be careful because this won't normally capture
> just method calls, but all attribute accesses.
> def reset_settings(self):
> method = None
> try:
> method = self.delegate.default_settings
> except AttributeError:
> ...
> If you think this example is contrived, maybe you haven't worked with
> the paradigms used in Objective-C very much.
I don't dispute it is real. I would say that it is RARE, but not contrived.
The example above was used
> dozens of times in a class that I wrote in Objective-C which draws a
> grid to the screen, for example, when it asks itself or its delegate
> what color the grid should be, or the maximum scale allowed. The
> practice is also used heavily by Apple's Cocoa libraries, which are my
> favorite UI libraries of all time to program with.
There is no question that some things take 2 lines in one programming
language and 5 in another. But let's say you wrap this pattern up in a
base class or metaclass or function. Is Python _still_ much more
complicated for this problem area than Objective-C? In this particular
case it should be easy to tell. What does Python/Cocoa code look like?
Surely you would agree that if a problem can be easily solved by a
little bit of code which can be saved in a library then it is not a
particularly deep problem. That's not the sort of thing I would switch
languages for. Now the differences between Java and Python are pretty
deep. Trying to make Python statically typed or O'CAML dynamically typed
is a Big Deal. But I really don't really see Python's regular expression
or "message capturing" conventions to be deep issues.
Paul Prescod
More information about the Python-list
mailing list