Interesting talk on Python vs. Ruby and how he would like Python to have just a bit more syntactic flexibility.

Kurt Smith kwmsmith at gmail.com
Fri Feb 19 00:37:59 EST 2010


On Thu, Feb 18, 2010 at 10:46 PM, Steve Howell <showell30 at yahoo.com> wrote:
> On Feb 18, 2:49 pm, Jonathan Gardner <jgard... at jonathangardner.net>
> wrote:
>> On Feb 18, 8:15 am, Steve Howell <showel... at yahoo.com> wrote:
>>
>>
>>
>> >     def print_numbers()
>> >         [1, 2, 3, 4, 5, 6].map { |n|
>> >             [n * n, n * n * n]
>> >         }.reject { |square, cube|
>> >             square == 25 || cube == 64
>> >         }.map { |square, cube|
>> >             cube
>> >         }.each { |n|
>> >             puts n
>> >         }
>> >     end
>>
>> If this style of programming were useful, we would all be writing Lisp
>> today. As it turned out, Lisp is incredibly difficult to read and
>> understand, even for experienced Lispers. I am pleased that Python is
>> not following Lisp in that regard.
>>
>> for n in range(1,6):
>>     square = n*n
>>     cube = n*n*n
>>     if square == 25 or cube == 64: continue
>>     print cube
>
> There's definitely a cognitive dissonance between imperative
> programming and functional programming.  It's hard for programmers
> used to programming in an imperative style to appreciate a functional
> approach, because functional solutions often read "upside down" in the
> actual source code and common algebraic notation:
>
>    def compute_squares_and_cubes(lst):
>        return [(n * n, n * n * n) for n in lst]
>
>    def reject_bad_values(lst):
>        return [(square, cube) for (square, cube) \
>            in lst if not (square == 25 or cube == 64)]
>
>    def cubes_only(lst):
>        return [cube for square, cube in lst]
>
>    def print_results(lst):
>        # 1. compute_squares_and_cubes
>        # 2. reject_bad_values
>        # 3. take cubes_only
>        # 4. print values
>        for item in \
>            cubes_only( # 3
>                reject_bad_values( # 2
>                    compute_squares_and_cubes(lst))): # 1
>            print item # 4
>
> You can, of course, restore the natural order of operations to read
> top-down with appropriate use of intermediate locals:
>
>    def print_results(lst):
>        lst2 = compute_squares_and_cubes(lst)
>        lst3 = reject_bad_values(lst2)
>        lst4 = cubes_only(lst3)
>        for item in lst4:
>            print item
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>

# sent the original to the wrong place -- resending to python-list.

Somewhat off topic, but only somewhat:  you could use coroutines to
get a pipeline effect.

#--------------8<-----------------------------
# Shamelessly lifted from David Beazley's
#  http://www.dabeaz.com/coroutines/

def coroutine(co):
   def _inner(*args, **kwargs):
       gen = co(*args, **kwargs)
       gen.next()
       return gen
   return _inner

def squares_and_cubes(lst, target):
   for n in lst:
       target.send((n * n, n * n * n))

@coroutine
def reject_bad_values(target):
   while True:
       square, cube = (yield)
       if not (square == 25 or cube == 64):
           target.send((square, cube))

@coroutine
def cubes_only(target):
   while True:
       square, cube = (yield)
       target.send(cube)

@coroutine
def print_results():
   while True:
       print (yield)

squares_and_cubes(range(10),
       reject_bad_values(
           cubes_only(
               print_results()
               )
           )
       )
#--------------8<-----------------------------



More information about the Python-list mailing list