[OPINION] - does language really matter if they all do the samething?

Paul Prescod paul at prescod.net
Sun Jan 25 00:24:33 CET 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