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

Steve Howell showell30 at yahoo.com
Fri Feb 19 07:44:16 CET 2010


On Feb 18, 9:37 pm, Kurt Smith <kwmsm... at gmail.com> wrote:
> On Thu, Feb 18, 2010 at 10:46 PM, Steve Howell <showel... 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()
>                )
>            )
>        )

Wow!  It took me a while to get my head around it, but that's pretty
cool.



More information about the Python-list mailing list