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

Dietrich Epp dietrich at zdome.net
Sun Jan 25 18:34:58 EST 2004


On Jan 25, 2004, at 7:14 AM, Aahz wrote:

> Well, choose_random_assoc() needs to dispatch on functions rather than
> values.  That will recurse only one level, and only in
> choose_random_assoc().  You'll also need to identify tuples in order to
> pass in values.  Here's a rewrite of Paul's function that shows roughly
> what you need to do:
>
> 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): ((random_sword_magic_power, medium),
>                 (random_sword_magic_power, medium)),
>             }
>
> Quite frankly, though, for this kind of application, I probably would
> choose to write a domain-specific language (more precisely, a "smart"
> config file format).  That would make it easier for someone who wasn't 
> a
> programmer to add functionality.  As I said earlier, I don't think the
> fact that Lisp makes it easy to directly express this idiom makes up 
> for
> its other faults.

Oh, I see.  I could write...

from random import *

def apply(x):
     x[0](*x[1:])

def apply_random(list):
     return apply(choose_random(list))

def choose_random(list):
     total = 0
     for probability, result in list:
         total += probability
     which = randint(total)
     for probability, result in list:
         if which < probability:
             return result
         which -= probability
     raise ValueError, "Probabilities sum to zero."

def random_sword_magical_power(quality):
     which_column = { poor:0, medium:1, good:2 }[quality]
     table = [
         ((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), (lambda: random_sword_magical_power(medium)
                            + random_sword_magical_power(medium)))
     ]
     table = [ (p[which_column], v) for (p,v) in table ]
     return apply_random(table)

...am I making this clearer?

Hint 1: What language is famous for its built-in function 'apply'?
Hint 2: What happens if you remove the commas in the table.

You may choose to write a domain-specific language.  This was my 
original idea as well.  The early versions of this program had the 
tables in XML files, and the Python code was short and sweet.  However, 
as I started writing some of the more complicated tables, I needed to 
write hooks in the XML back into Python, and eventually one of the XML 
files saw the presence of a few 'lambdas' here and there.  I changed 
the XML files, I refactored the Python code, but XML didn't integrate 
code well enough with its data, and Python didn't integrate data well 
enough with its code.  The Lisp code that replaced everything is 
smaller, faster, easier to read, and easier to write.

My only point is that Python is not the right tool for every project.  
I only see two ways to make this read well in Python: either add macros 
(like Lisp, NOT like C) or add blocks that don't use lambda (like 
Smalltalk or Ruby).  I prefer Python's syntax the way it is.





More information about the Python-list mailing list