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

2010-02-23 Thread Anh Hai Trinh
On Feb 23, 1:03 pm, Alf P. Steinbach al...@start.no wrote:

 Uhm, Paganini...

 As I understand it he invented the destroy your instruments on stage. :-)

 Cheers,

 - Alf (off-topic)

You probably meant Franz Liszt, who regularly broke piano strings.
Paganini was also a rock-star virtuoso but he did not destroy any
Guarnerius or Stradivarius violins in his possession (at least not to
anyone's knowledge :)

As for functional programming, different people take it to mean
different things. For some, simply using first-class functions
qualifies as functional programming.  Others require their functions
to be pure so that their call graphs can be automatically reduced and
their results can be lazily evaluated.  If you takes the former view,
most Python programmers already do functional programming :p

--aht
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-23 Thread Timothy N. Tsvetkov
On Feb 16, 10:41 pm, Andrej Mitrovic andrej.mitrov...@gmail.com
wrote:
 On Feb 16, 7:38 pm, Casey Hawthorne caseyhhammer_t...@istar.ca
 wrote:

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

 http://blog.extracheese.org/2010/02/python-vs-ruby-a-battle-to-the-de...
  --
  Regards,
  Casey

 Gary's friend Geoffrey Grosenbach says in his blog post (which Gary
 linked to): Python has no comparable equivalent to Ruby’s do end
 block. Python lambdas are limited to one line and can’t contain
 statements (for, if, def, etc.). Which leaves me wondering, what’s the
 point?

 I'm sorry, lambda's do support if's and for's. Also, lambda's are
 expressions, not statements, but you can pass them around, keep them
 in a dictionary if you want to. And if you need more than one line of
 statements, for crying out loud use a def? And who needs those do-
 end blocks anyway, trying to turn Python into Pascal?

I think there are some nice use-cases for anonymous functions /
blocks. First, mentioned above, is pretty DSL. And the second is using
blocks in map/reduce functions. Yes, you can pass there a function but
I believe that in most situations it is more readable to pass a
multiline anonymous function / block than defined somewhere function
written only for a single map/reduce operation. And often when you use
reduce it is a bit more complicated then just one line function.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-22 Thread Jonathan Gardner
On Sun, Feb 21, 2010 at 10:22 AM, John Bokma j...@castleamber.com wrote:
 Jonathan Gardner jgard...@jonathangardner.net writes:
 On Fri, Feb 19, 2010 at 11:16 PM, Lie Ryan lie.1...@gmail.com wrote:

 Now, why don't we start a PEP to make python a fully-functional language
 then?

 Because people don't think the same way that programs are written in
 functional languages.

 Heh! When I learned Miranda it felt natural to me. Prolog on the other
 hand...

 In short: I am afraid you're overgeneralizing here; it depends on one's
 background. If not, citation needed ;-)


Unfortunately, this is something that is hardly measurable. Short of a
survey (of whom? of what?), there can be no objective evaluation. To
date, I don't know of any such studies or surveys.

I won't deny that really smart people enjoy the challenge of
programming in a functional style, and some even find it easier to
work with. However, when it comes to readability and maintenance, I
appreciate the statement-based programming style, simply because it's
easier for me to understand an debug.

-- 
Jonathan Gardner
jgard...@jonathangardner.net
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-22 Thread Paul Rubin
Jonathan Gardner jgard...@jonathangardner.net writes:
 I won't deny that really smart people enjoy the challenge of
 programming in a functional style, and some even find it easier to
 work with. However, when it comes to readability and maintenance, I
 appreciate the statement-based programming style, simply because it's
 easier for me to understand an debug.

One thing those people are after is programs that work properly the
first time they are run, and thus don't need debugging.  They achieve
that a surprising amount of the time.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-22 Thread John Bokma
Jonathan Gardner jgard...@jonathangardner.net writes:

 On Sun, Feb 21, 2010 at 10:22 AM, John Bokma j...@castleamber.com wrote:
 Jonathan Gardner jgard...@jonathangardner.net writes:
 On Fri, Feb 19, 2010 at 11:16 PM, Lie Ryan lie.1...@gmail.com wrote:

 Now, why don't we start a PEP to make python a fully-functional language
 then?

 Because people don't think the same way that programs are written in
 functional languages.

 Heh! When I learned Miranda it felt natural to me. Prolog on the other
 hand...

 In short: I am afraid you're overgeneralizing here; it depends on one's
 background. If not, citation needed ;-)


 Unfortunately, this is something that is hardly measurable. Short of a
 survey (of whom? of what?), there can be no objective evaluation. To
 date, I don't know of any such studies or surveys.

 I won't deny that really smart people enjoy the challenge of
 programming in a functional style, and some even find it easier to
 work with. However, when it comes to readability and maintenance, I
 appreciate the statement-based programming style, simply because it's
 easier for me to understand an debug.

In my class there where basically 2 groups of people: the ones who got
functional programming and the ones who had a hard time with it. The
latter group consisted mostly of people who had been programming in
languages like C and Pascal for years; they had a hard time thinking
functionally. The former group consisted mostly of people who had little
or no programming experience, with a few exceptions (including me :-) ).

So I have the feeling it has more to do with your background then how
people think / are wired.

-- 
John Bokma   j3b

Hacking  Hiking in Mexico -  http://johnbokma.com/
http://castleamber.com/ - Perl  Python Development
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-22 Thread Lawrence D'Oliveiro
In message 1ecc71bf-54ab-45e6-a38a-d1861f092...@v25g2000yqk.googlegroups.com, 
sjdevn...@yahoo.com wrote:

 On Feb 20, 1:30 am, Lawrence D'Oliveiro l...@geek-central.gen.new_zealand 
 wrote:

 In message op.u8at0suda8n...@gnudebst, Rhodri James wrote:

  In classic Pascal, a procedure was distinct from a function in that it
  had no return value.  The concept doesn't really apply in Python; there
  are no procedures in that sense, since if a function terminates without
  supplying an explicit return value it returns None.

 If Python doesn’t distinguish between procedures and functions, why
 should it distinguish between statements and expressions?
 
 Because the latter are different in Python (and in Ruby, and in most
 modern languages), while the former aren't distinguished in Python or
 Ruby or most modern languages?  Primarily functional languages are the
 main exception, but other than them it's pretty uncommon to find any
 modern language that does distinguish procedures and functions, or one
 that doesn't distinguished statements and expressions.
 
 You can certainly find exceptions, but distinguishing statements and
 expressions is absolutely commonplace in modern languages, and
 distinguishing functions and procedures is in the minority.

So they are worth distinguishing where they are distinguished, except where
they’re not?
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-22 Thread Paul Rubin
John Bokma j...@castleamber.com writes:
 In my class there where basically 2 groups of people: the ones who got
 functional programming and the ones who had a hard time with it. The
 latter group consisted mostly of people who had been programming in
 languages like C and Pascal for years; they had a hard time thinking
 functionally. 

I've heard it expressed this way (paraphrased): functional programming
has a steep unlearning curve.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-22 Thread Lawrence D'Oliveiro
In message 
3aa0205f-1e98-4376-92e4-607f96f13...@k19g2000yqc.googlegroups.com, Michael 
Sparks wrote:

 [1] This is perhaps more appropriate because '(a b c) is equivalent
 to (quote a b c), and quote a b c can be viewed as close to
 python's expression lambda: a b c

You got to be kidding.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-22 Thread Jonathan Gardner
On Mon, Feb 22, 2010 at 12:31 PM, John Bokma j...@castleamber.com wrote:

 In my class there where basically 2 groups of people: the ones who got
 functional programming and the ones who had a hard time with it. The
 latter group consisted mostly of people who had been programming in
 languages like C and Pascal for years; they had a hard time thinking
 functionally. The former group consisted mostly of people who had little
 or no programming experience, with a few exceptions (including me :-) ).

 So I have the feeling it has more to do with your background then how
 people think / are wired.


That's encouraging. If functional programming is really more natural
to those who are less familiar with math and programming, then perhaps
there is a future for it.

Unfortunately, I don't know that just knowing how to program
functionally is enough. Even the functional folks have a hard time
optimizing routines (time or memory). Even with DBAs, they have to
know how the functional SQL query is translated into discrete machine
instructions.

As it is now, the vast majority (all?) of the programmers who do any
programming seriously are familiar with the statement-based approach.
A minority understand let alone appreciate the functional approach.

-- 
Jonathan Gardner
jgard...@jonathangardner.net
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-22 Thread Steve Howell
On Feb 22, 8:35 pm, Jonathan Gardner jgard...@jonathangardner.net
wrote:
 On Mon, Feb 22, 2010 at 12:31 PM, John Bokma j...@castleamber.com wrote:

  In my class there where basically 2 groups of people: the ones who got
  functional programming and the ones who had a hard time with it. The
  latter group consisted mostly of people who had been programming in
  languages like C and Pascal for years; they had a hard time thinking
  functionally. The former group consisted mostly of people who had little
  or no programming experience, with a few exceptions (including me :-) ).

  So I have the feeling it has more to do with your background then how
  people think / are wired.

 That's encouraging. If functional programming is really more natural
 to those who are less familiar with math and programming, then perhaps
 there is a future for it.

 Unfortunately, I don't know that just knowing how to program
 functionally is enough. Even the functional folks have a hard time
 optimizing routines (time or memory). Even with DBAs, they have to
 know how the functional SQL query is translated into discrete machine
 instructions.

 As it is now, the vast majority (all?) of the programmers who do any
 programming seriously are familiar with the statement-based approach.
 A minority understand let alone appreciate the functional approach.


Hi Jonathon.  I understand three major programming paradigms--
imperative, OO, and functional.  My first instinct is always
imperative, as I just want the computer to *do* stuff.

I am not an expert in any paradigm and it is possible that I am
overlooking other major paradigms.

My gut instinct is that functional programming works well for lots of
medium sized problems and it is worth learning.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-22 Thread Paul Rubin
Steve Howell showel...@yahoo.com writes:
 My gut instinct is that functional programming works well for lots of
 medium sized problems and it is worth learning.

I think it's worth learning because it will make you a better programmer
even if you never use it for anything beyond academic exercises.  It's
just like playing Bach fugues in some of your practice hours will make
you a better musician even if you are professionally a heavy metal rock
guitarist.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-22 Thread Steve Howell
On Feb 22, 9:11 pm, Steve Howell showel...@yahoo.com wrote:
 On Feb 22, 8:35 pm, Jonathan Gardner jgard...@jonathangardner.net
 wrote:



  On Mon, Feb 22, 2010 at 12:31 PM, John Bokma j...@castleamber.com wrote:

   In my class there where basically 2 groups of people: the ones who got
   functional programming and the ones who had a hard time with it. The
   latter group consisted mostly of people who had been programming in
   languages like C and Pascal for years; they had a hard time thinking
   functionally. The former group consisted mostly of people who had little
   or no programming experience, with a few exceptions (including me :-) ).

   So I have the feeling it has more to do with your background then how
   people think / are wired.

  That's encouraging. If functional programming is really more natural
  to those who are less familiar with math and programming, then perhaps
  there is a future for it.

  Unfortunately, I don't know that just knowing how to program
  functionally is enough. Even the functional folks have a hard time
  optimizing routines (time or memory). Even with DBAs, they have to
  know how the functional SQL query is translated into discrete machine
  instructions.

  As it is now, the vast majority (all?) of the programmers who do any
  programming seriously are familiar with the statement-based approach.
  A minority understand let alone appreciate the functional approach.

 Hi Jonathon.  I understand three major programming paradigms--
 imperative, OO, and functional.  My first instinct is always
 imperative, as I just want the computer to *do* stuff.

 I am not an expert in any paradigm and it is possible that I am
 overlooking other major paradigms.

 My gut instinct is that functional programming works well for lots of
 medium sized problems and it is worth learning.

Sorry for misspelling your name, and yes I agree that you always want
some notion of what happens under the covers (in any paradigm).
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-22 Thread Steve Howell
On Feb 22, 9:06 pm, Paul Rubin no.em...@nospam.invalid wrote:
 Steve Howell showel...@yahoo.com writes:
  My gut instinct is that functional programming works well for lots of
  medium sized problems and it is worth learning.

 I think it's worth learning because it will make you a better programmer
 even if you never use it for anything beyond academic exercises.  It's
 just like playing Bach fugues in some of your practice hours will make
 you a better musician even if you are professionally a heavy metal rock
 guitarist.

Well said, and your analogy is based in fact--some pretty awesome rock
guitarists have training in classical and jazz.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-22 Thread Alf P. Steinbach

* Paul Rubin:

Steve Howell showel...@yahoo.com writes:

My gut instinct is that functional programming works well for lots of
medium sized problems and it is worth learning.


I think it's worth learning because it will make you a better programmer
even if you never use it for anything beyond academic exercises.  It's
just like playing Bach fugues in some of your practice hours will make
you a better musician even if you are professionally a heavy metal rock
guitarist.


Uhm, Paganini...

As I understand it he invented the destroy your instruments on stage. :-)


Cheers,

- Alf (off-topic)
--
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-21 Thread John Bokma
Jonathan Gardner jgard...@jonathangardner.net writes:

 On Fri, Feb 19, 2010 at 11:16 PM, Lie Ryan lie.1...@gmail.com wrote:

 Now, why don't we start a PEP to make python a fully-functional language
 then?

 Because people don't think the same way that programs are written in
 functional languages.

Heh! When I learned Miranda it felt natural to me. Prolog on the other
hand...

In short: I am afraid you're overgeneralizing here; it depends on one's
background. If not, citation needed ;-)

-- 
John Bokma   j3b

Hacking  Hiking in Mexico -  http://johnbokma.com/
http://castleamber.com/ - Perl  Python Development
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-20 Thread Jonathan Gardner
On Fri, Feb 19, 2010 at 11:16 PM, Lie Ryan lie.1...@gmail.com wrote:

 Now, why don't we start a PEP to make python a fully-functional language
 then?


Because people don't think the same way that programs are written in
functional languages.

-- 
Jonathan Gardner
jgard...@jonathangardner.net
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-20 Thread Chris Rebert
On Fri, Feb 19, 2010 at 11:17 PM, sjdevn...@yahoo.com
sjdevn...@yahoo.com wrote:
 On Feb 20, 1:30 am, Lawrence D'Oliveiro l...@geek-
 central.gen.new_zealand wrote:
 If Python doesn’t distinguish between procedures and functions, why should
 it distinguish between statements and expressions?

 Because the latter are different in Python (and in Ruby

I think your Ruby assertion needs fact-checking:

irb(main):001:0 a = 7  # assignments have a value
= 7
irb(main):002:0 puts(b = 42)  # as further proof
42
= nil
irb(main):003:0 b
= 42
irb(main):004:0 c = [6,4,5]
= [6, 4, 5]
irb(main):005:0 if false
irb(main):006:1   c.reverse!
irb(main):007:1 else
irb(main):008:1*   c.sort!
irb(main):009:1 end  # even the if-else control structure has a value
= [4, 5, 6]
irb(main):010:0 begin # same with exception handling
irb(main):011:1*raise a runtime error
irb(main):012:1 rescue RuntimeError
irb(main):013:1   sounds bad
irb(main):014:1 end
= sounds bad
irb(main):015:0 def foo # and same with method bodies
irb(main):016:1   99
irb(main):017:1 end
= nil
irb(main):018:0 foo
= 99

Quoth Wikipedia regarding Ruby (programming language):
For practical purposes there is no distinction between expressions
and statements

Cheers,
Chris
--
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-20 Thread Michael Sparks
On Feb 18, 4:15 pm, Steve Howell showel...@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

This strikes me as a terrible example. For example, this is
significantly clearer:
def print_numbers()
for n in [1,2,3,4,5,6]:
square, cube = n * n, n * n * n
if square != 25 and cube != 64:
print n

I /can/ see arguments for ruby style blocks in python, but not for
this sort of thing, or lisp style quoted expressions[1]. ie I can see
situations where you have more complex code in real life where they
will definitely simplify things.

[1] This is perhaps more appropriate because '(a b c) is equivalent
to (quote a b c), and quote a b c can be viewed as close to
python's expression lambda: a b c

However, I can also see that in simple situations - such as the
example you post - they will have a tendency to make code
significantly less clear/direct.

I suppose, if I have a choice between something (hard being possible 
simple code looking simple) and (hard things being simpler  simple
things looking harder), I'd probably personally choose the former.
This is not because I don't like hard things being simple, but because
I think that simple things are more common and making them look harder
is a mistake.

I'm well aware that's opinion however,

Regards,


Michael.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-20 Thread Steve Howell
On Feb 20, 6:13 am, Michael Sparks spark...@gmail.com wrote:
 On Feb 18, 4:15 pm, Steve Howell showel...@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

 This strikes me as a terrible example. For example, this is
 significantly clearer:
     def print_numbers()
         for n in [1,2,3,4,5,6]:
             square, cube = n * n, n * n * n
             if square != 25 and cube != 64:
                 print n

This is not an exact translation.  My example prints the cubes.  It is
my fault for using n as the parameter in the last block.  I would
rename the parameter to cube.


 I /can/ see arguments for ruby style blocks in python, but not for
 this sort of thing, or lisp style quoted expressions[1]. ie I can see
 situations where you have more complex code in real life where they
 will definitely simplify things.

 [1] This is perhaps more appropriate because '(a b c) is equivalent
     to (quote a b c), and quote a b c can be viewed as close to
     python's expression lambda: a b c

 However, I can also see that in simple situations - such as the
 example you post - they will have a tendency to make code
 significantly less clear/direct.

 I suppose, if I have a choice between something (hard being possible 
 simple code looking simple) and (hard things being simpler  simple
 things looking harder), I'd probably personally choose the former.
 This is not because I don't like hard things being simple, but because
 I think that simple things are more common and making them look harder
 is a mistake.



I agree with much of what you are saying.  The example is indeed
terribly contrived.

I'm not sure I agree that there is anything unclear or undirect about
the Ruby, though.  I've been fairly immersed in Ruby code, so maybe
it's been warping my brain, but once you get over the unfamiliarity of
the syntax, you see that there's actually a rhythm to the code.

Setting aside punctuation and parameter lists, the code clearly
expresses the transformations and actions in the natural order that
you'd do them:

   LIST map
  expression
reject
  criteria
map
  expression
each
  statement

In English, for the list elements, map them to tuples of squares and
cubes, reject the oddballs, take the cube, and print it out.

 [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 { |cube|
 puts cube
 }

For such a small problem, I agree it's verbose.   But it's also
completely flat--you don't need to use an if statement to express
the concept of rejection.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Anh Hai Trinh
On Feb 19, 1:44 pm, Steve Howell showel...@yahoo.com wrote:

  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.


This pipeline idea has actually been implemented further, see http://
blog.onideas.ws/stream.py.

  from stream import map, filter, cut
  range(10)  map(lambda x: [x**2, x**3])  filter(lambda t: t[0]!
=25 and t[1]!=64)  cut[1]  list
  [0, 1, 8, 27, 216, 343, 512, 729]


--
aht
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Roald de Vries

This pipeline idea has actually been implemented further, see http://
blog.onideas.ws/stream.py.

from stream import map, filter, cut
range(10)  map(lambda x: [x**2, x**3])  filter(lambda t: t[0]!
=25 and t[1]!=64)  cut[1]  list
[0, 1, 8, 27, 216, 343, 512, 729]


Wow, cool!

Just to show that you can easily add the iterator.map(f).blabla-syntax  
to Python:


from __future__ import print_function

class rubified(list):
map= lambda self, f: rubified(map(f, self))
filter = lambda self, f: rubified(filter(f, self))
reject = lambda self, f: rubified(filter(lambda x: not f(x),  
self))
# each = lambda self, f: rubified(reduce(lambda x, y:  
print(y), self, None))

def each(self, f):
for x in self: f(x)

def __new__(cls, value):
return list.__new__(cls, value)

def print_numbers():
rubified([1, 2, 3, 4, 5, 6]).map(lambda n:
[n * n, n * n * n]).reject(lambda (square, cube):
square == 25 or cube == 64).map(lambda (square, cube):
cube).each(lambda n:
print(n))



--
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Steve Howell
On Feb 19, 7:50 am, Roald de Vries r...@roalddevries.nl wrote:
  This pipeline idea has actually been implemented further, see http://
  blog.onideas.ws/stream.py.

  from stream import map, filter, cut
  range(10)  map(lambda x: [x**2, x**3])  filter(lambda t: t[0]!
  =25 and t[1]!=64)  cut[1]  list
  [0, 1, 8, 27, 216, 343, 512, 729]

 Wow, cool!

 Just to show that you can easily add the iterator.map(f).blabla-syntax  
 to Python:

      from __future__ import print_function

      class rubified(list):
          map    = lambda self, f: rubified(map(f, self))
          filter = lambda self, f: rubified(filter(f, self))
          reject = lambda self, f: rubified(filter(lambda x: not f(x),  
 self))
          # each = lambda self, f: rubified(reduce(lambda x, y:  
 print(y), self, None))
          def each(self, f):
              for x in self: f(x)

          def __new__(cls, value):
              return list.__new__(cls, value)

      def print_numbers():
          rubified([1, 2, 3, 4, 5, 6]).map(lambda n:
              [n * n, n * n * n]).reject(lambda (square, cube):
              square == 25 or cube == 64).map(lambda (square, cube):
              cube).each(lambda n:
              print(n))

Sure, that definitely achieves the overall sequential structure of
operations that I like in Ruby.  A couple other example have been
posted as well now, which also mimic something akin to a Unix
pipeline.

A lot of Ruby that I see gets spelled like this:

   list.select { |arg1, arg2|
  expr
   }.reject { |arg|
  expr
   }.collect { |arg}
  expr
   }

With your class you can translate into Python as follows:

   list.select(lambda arg1, arg2:
  expr
   ).reject(lambda arg:
  expr
   ).collect(lambda arg:
  expr
   )

So for chaining transformations based on filters, the difference
really just comes down to syntax (and how much sugar is built into the
core library).

The extra expressiveness of Ruby comes from the fact that you can add
statements within the block, which I find useful sometimes just for
debugging purposes:

debug = true
data = strange_dataset_from_third_party_code()
data.each { |arg|
if debug and arg  1
puts arg
end
# square the values
arg * arg
}




-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Steven D'Aprano
On Fri, 19 Feb 2010 08:32:53 -0800, Steve Howell wrote:

 The extra expressiveness of Ruby comes from the fact that you can add
 statements within the block, which I find useful sometimes just for
 debugging purposes:
 
 debug = true
 data = strange_dataset_from_third_party_code() 
 data.each { |arg|
 if debug and arg  1
 puts arg
 end
 # square the values
 arg * arg
 }

How is that different from this?

debug = true
data = strange_dataset_from_third_party_code() 
for i, arg in enumerate(data):
if debug and arg  1
print arg
# square the values
data[i] = arg * arg


I don't see the extra expressiveness. What I see is that the Ruby snippet 
takes more lines (even excluding the final brace), and makes things 
implicit which in my opinion should be explicit. But since I'm no Ruby 
expert, perhaps I'm misreading it.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Steve Howell
On Feb 19, 9:30 am, Steven D'Aprano st...@remove-this-
cybersource.com.au wrote:
 On Fri, 19 Feb 2010 08:32:53 -0800, Steve Howell wrote:
  The extra expressiveness of Ruby comes from the fact that you can add
  statements within the block, which I find useful sometimes just for
  debugging purposes:

      debug = true
      data = strange_dataset_from_third_party_code()
      data.each { |arg|
          if debug and arg  1
              puts arg
          end
          # square the values
          arg * arg
      }

 How is that different from this?

 debug = true
 data = strange_dataset_from_third_party_code()
 for i, arg in enumerate(data):
     if debug and arg  1
         print arg
     # square the values
     data[i] = arg * arg

 I don't see the extra expressiveness. What I see is that the Ruby snippet
 takes more lines (even excluding the final brace), and makes things
 implicit which in my opinion should be explicit. But since I'm no Ruby
 expert, perhaps I'm misreading it.


You are reading the example out of context.

Can you re-read the part you snipped?

The small piece of code can obviously be written imperatively, but the
point of the example was not to print a bunch of squares.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Lie Ryan
On 02/19/10 14:57, Steve Howell wrote:
 In a more real world example, the intermediate results would be
 something like this:
 
departments
departments_in_new_york
departments_in_new_york_not_on_bonus_cycle
employees_in_departments_in_new_york_not_on_bonus_cycle
names_of_employee_in_departments_in_new_york_not_on_bonus_cycle
 

I fare better, in less than ten-seconds thinking:

departments
eligible_departments
eligible_departments
eligible_employees
eligible_employee_names

as a bonus, they would be much more resilient when there are change of
eligibility requirements.

Names doesn't have to exactly describe what's in it; in fact, if your
names is way too descriptive, it may take significantly more brain-cycle
to parse. A good name abstracts the objects contained in it.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Lawrence D'Oliveiro
In message 87eikjcuzk@benfinney.id.au, Ben Finney wrote:

 Lawrence D'Oliveiro l...@geek-central.gen.new_zealand writes:
 
 In message hlhdsi$2p...@theodyn.ncf.ca, cjw wrote:

  Aren't lambda forms better described as function?

 Is this a function?

 lambda : None

 What about this?

 lambda : sys.stdout.write(hi there!\n)
 
 They are both lambda forms in Python. As a Python expression, they
 evaluate to (they “return”) a function object.

So there is no distinction between functions and procedures, then?
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Lawrence D'Oliveiro
In message 84166541-c10a-47b5-ae5b-
b23202624...@q2g2000pre.googlegroups.com, Steve Howell wrote:

 Some people make the definition of function more restrictive--if it
 has side effects, it is not a function.

Does changing the contents of CPU cache count as a side-effect?
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Lawrence D'Oliveiro
In message op.u8at0suda8n...@gnudebst, Rhodri James wrote:

 In classic Pascal, a procedure was distinct from a function in that it had
 no return value.  The concept doesn't really apply in Python; there are no
 procedures in that sense, since if a function terminates without supplying
 an explicit return value it returns None.

If Python doesn’t distinguish between procedures and functions, why should 
it distinguish between statements and expressions?
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Ben Finney
Lawrence D'Oliveiro l...@geek-central.gen.new_zealand writes:

 So there is no distinction between functions and procedures, then?

In Python, no.

-- 
 \ “When we pray to God we must be seeking nothing — nothing.” |
  `\  —Saint Francis of Assisi |
_o__)  |
Ben Finney
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Steve Holden
Ben Finney wrote:
 Lawrence D'Oliveiro l...@geek-central.gen.new_zealand writes:
 
 If Python doesn’t distinguish between procedures and functions, why
 should it distinguish between statements and expressions?
 
 I don't see the connection between those two predicates. Why does the
 former matter when determining the “should” of the latter?
 
Because s similar dichotomy exists between the two pairs.

Procedure = function not returning a value
Statement = expression not returning a value

regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
PyCon is coming! Atlanta, Feb 2010  http://us.pycon.org/
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS:http://holdenweb.eventbrite.com/

-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread sjdevn...@yahoo.com
On Feb 20, 1:28 am, Lawrence D'Oliveiro l...@geek-
central.gen.new_zealand wrote:
 In message 87eikjcuzk@benfinney.id.au, Ben Finney wrote:



  Lawrence D'Oliveiro l...@geek-central.gen.new_zealand writes:

  In message hlhdsi$2p...@theodyn.ncf.ca, cjw wrote:

   Aren't lambda forms better described as function?

  Is this a function?

      lambda : None

  What about this?

      lambda : sys.stdout.write(hi there!\n)

  They are both lambda forms in Python. As a Python expression, they
  evaluate to (they “return”) a function object.

 So there is no distinction between functions and procedures, then?

Not in most modern languages, no.  i think the major places they are
differentiated are in functional languages and in pre-1993ish
languages (give or take a few years), neither of which applies to
Python or Ruby.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread sjdevn...@yahoo.com
On Feb 20, 1:30 am, Lawrence D'Oliveiro l...@geek-
central.gen.new_zealand wrote:
 In message op.u8at0suda8n...@gnudebst, Rhodri James wrote:

  In classic Pascal, a procedure was distinct from a function in that it had
  no return value.  The concept doesn't really apply in Python; there are no
  procedures in that sense, since if a function terminates without supplying
  an explicit return value it returns None.

 If Python doesn’t distinguish between procedures and functions, why should
 it distinguish between statements and expressions?

Because the latter are different in Python (and in Ruby, and in most
modern languages), while the former aren't distinguished in Python or
Ruby or most modern languages?  Primarily functional languages are the
main exception, but other than them it's pretty uncommon to find any
modern language that does distinguish procedures and functions, or one
that doesn't distinguished statements and expressions.

You can certainly find exceptions, but distinguishing statements and
expressions is absolutely commonplace in modern languages, and
distinguishing functions and procedures is in the minority.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Lie Ryan
On 02/20/10 17:30, Lawrence D'Oliveiro wrote:
 In message op.u8at0suda8n...@gnudebst, Rhodri James wrote:
 
 In classic Pascal, a procedure was distinct from a function in that it had
 no return value.  The concept doesn't really apply in Python; there are no
 procedures in that sense, since if a function terminates without supplying
 an explicit return value it returns None.
 
 If Python doesn’t distinguish between procedures and functions, why should 
 it distinguish between statements and expressions?

There are non-trivial languages that have been made without procedures
and statements and non-trivial programs written on those languages.
There is technically no need for a lambda that supports statements;
someone could simply write a full-blown Monad framework and all of the
things required for IO Monad and all their syntax sugars up to near a
level of Haskell. Then we can do away with 'def's and all the statements
or make them syntax sugar for the Monads.

Now, why don't we start a PEP to make python a fully-functional language
then?
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Lie Ryan
On 02/20/10 18:17, sjdevn...@yahoo.com wrote:
 On Feb 20, 1:30 am, Lawrence D'Oliveiro l...@geek-
 central.gen.new_zealand wrote:
 In message op.u8at0suda8n...@gnudebst, Rhodri James wrote:

 In classic Pascal, a procedure was distinct from a function in that it had
 no return value.  The concept doesn't really apply in Python; there are no
 procedures in that sense, since if a function terminates without supplying
 an explicit return value it returns None.

 If Python doesn’t distinguish between procedures and functions, why should
 it distinguish between statements and expressions?
 
 Because the latter are different in Python (and in Ruby, and in most
 modern languages), while the former aren't distinguished in Python or
 Ruby or most modern languages?  Primarily functional languages are the
 main exception, but other than them it's pretty uncommon to find any
 modern language that does distinguish procedures and functions, or one
 that doesn't distinguished statements and expressions.
 
 You can certainly find exceptions, but distinguishing statements and
 expressions is absolutely commonplace in modern languages, and
 distinguishing functions and procedures is in the minority.

But it all boils down to Although practicality beats purity.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Carl Banks
On Feb 19, 10:30 pm, Lawrence D'Oliveiro l...@geek-
central.gen.new_zealand wrote:
 In message op.u8at0suda8n...@gnudebst, Rhodri James wrote:

  In classic Pascal, a procedure was distinct from a function in that it had
  no return value.  The concept doesn't really apply in Python; there are no
  procedures in that sense, since if a function terminates without supplying
  an explicit return value it returns None.

 If Python doesn’t distinguish between procedures and functions, why should
 it distinguish between statements and expressions?

Because the real world works is more complex than simplified one-
sentence generalizations.


Carl Bnkas
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-19 Thread Carl Banks
On Feb 19, 11:12 pm, Steve Holden st...@holdenweb.com wrote:
 Ben Finney wrote:
  Lawrence D'Oliveiro l...@geek-central.gen.new_zealand writes:

  If Python doesn’t distinguish between procedures and functions, why
  should it distinguish between statements and expressions?

  I don't see the connection between those two predicates. Why does the
  former matter when determining the “should” of the latter?

 Because s similar dichotomy exists between the two pairs.

 Procedure = function not returning a value
 Statement = expression not returning a value

So if your language distinguishes between procedures and functions, it
manifestly has to distinguish between statements and expressions, but
there's no reason that the converse has to be true, expecially if an
expression is a legal statement.


Carl Banks
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Duncan Booth
Jonathan Gardner jgard...@jonathangardner.net wrote:

 On Feb 17, 12:02 am, Lawrence D'Oliveiro l...@geek-
 central.gen.new_zealand wrote:
 In message
 8ca440b2-6094-4b35-80c5-81d000517...@v20g2000prb.googlegroups.com,

 Jonathan Gardner wrote:
  I used to think anonymous functions (AKA blocks, etc...) would be a
  nice feature for Python.

  Then I looked at a stack trace from a different programming
  language with lots of anonymous functions. (I believe it was perl.)

 Didn’t it have source line numbers in it?

 What more do you need?
 
 I don't know, but I tend to find the name of the function I called to
 be useful. It's much more memorable than line numbers, particularly
 when line numbers keep changing.
 
 I doubt it's just me, though.

Some problems with using just line numbers to track errors:

In any language it isn't much use if you get a bug report from a shipped
program that says there was an error on line 793 but no report of
exactly which version of the shipped code was being run. 

Microsoft love telling you the line number: if IE gets a Javascript
error it reports line number but not filename, so you have to guess
which of the HTML page or one of many included files actually had the
error. Plus the line number that is reported is often slightly off. 

Javascript in particular is often sent to the browser compressed then
uncompressed and eval'd. That makes line numbers completely useless for
tracking down bugs as you'll always get the line number of the eval.
Also the way functions are defined in Javascript means you'll often have
almost every function listed in a backtrace as 'Anonymous'. 

-- 
Duncan Booth http://kupuguy.blogspot.com
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steve Howell
On Feb 18, 1:23 am, Duncan Booth duncan.bo...@invalid.invalid wrote:
 Jonathan Gardner jgard...@jonathangardner.net wrote:
  On Feb 17, 12:02 am, Lawrence D'Oliveiro l...@geek-
  central.gen.new_zealand wrote:
  In message
  8ca440b2-6094-4b35-80c5-81d000517...@v20g2000prb.googlegroups.com,

  Jonathan Gardner wrote:
   I used to think anonymous functions (AKA blocks, etc...) would be a
   nice feature for Python.

   Then I looked at a stack trace from a different programming
   language with lots of anonymous functions. (I believe it was perl.)

  Didn’t it have source line numbers in it?

  What more do you need?

  I don't know, but I tend to find the name of the function I called to
  be useful. It's much more memorable than line numbers, particularly
  when line numbers keep changing.

  I doubt it's just me, though.

 Some problems with using just line numbers to track errors:

 In any language it isn't much use if you get a bug report from a shipped
 program that says there was an error on line 793 but no report of
 exactly which version of the shipped code was being run.

 Microsoft love telling you the line number: if IE gets a Javascript
 error it reports line number but not filename, so you have to guess
 which of the HTML page or one of many included files actually had the
 error. Plus the line number that is reported is often slightly off.

 Javascript in particular is often sent to the browser compressed then
 uncompressed and eval'd. That makes line numbers completely useless for
 tracking down bugs as you'll always get the line number of the eval.
 Also the way functions are defined in Javascript means you'll often have
 almost every function listed in a backtrace as 'Anonymous'.

If this is an argument against using anonymous functions, then it is a
quadruple strawman.

Shipping buggy code is a bad idea, even with named functions.

Obscuring line numbers is a bad idea, even with named functions.

Having your customers stay on older versions of your software is a bad
idea, even with named functions.

Not being able to know which version of software you're customer is
running is a bad idea, even with named functions.

Of course, using anonymous functions in no way prevents you from
capturing a version number in a traceback.  And in most modern source
control systems, it is fairly easy to revert to an old version of that
code.

def factory():
return lambda: 15 / 0

def bar(method):
method()

def foo(method):
bar(method)

def baz(method):
foo(method)

try:
baz(factory())
except:
print 'problem with version 1.234a'
raise

problem with version 1.234a
Traceback (most recent call last):
  File foo.py, line 14, in module
baz(factory())
  File foo.py, line 11, in baz
foo(method)
  File foo.py, line 8, in foo
bar(method)
  File foo.py, line 5, in bar
method()
  File foo.py, line 2, in lambda
return lambda: 15 / 0
ZeroDivisionError: integer division or modulo by zero
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Duncan Booth
Steve Howell showel...@yahoo.com wrote:

 If this is an argument against using anonymous functions, then it is a
 quadruple strawman.
 
 Shipping buggy code is a bad idea, even with named functions.

I doubt very much whether I have ever shipped any bug-free code but
even if it was fit for purpose when shipped it is quite possible that the 
software will interact badly with other software that did not exist at the 
time of shipping.

 
 Obscuring line numbers is a bad idea, even with named functions.

In principle I agree, but where Javascript is concerned compressing the 
downloaded files is generally a pretty good idea and practicality beats 
purity.

 
 Having your customers stay on older versions of your software is a bad
 idea, even with named functions.

I think that's their decision, not mine.

 
 Not being able to know which version of software you're customer is
 running is a bad idea, even with named functions.
 
I agree, but getting a complete coherent description out of a customer is 
not always an easy task. (I'm reading the word 'customer' here to include 
the case where there is no monetary relationship between the software 
author and the entity using it, but even when there is I think this still 
true.)


-- 
Duncan Booth http://kupuguy.blogspot.com
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steven D'Aprano
On Thu, 18 Feb 2010 06:15:20 -0800, Steve Howell wrote:

 On Feb 18, 1:23 am, Duncan Booth duncan.bo...@invalid.invalid wrote:
 Jonathan Gardner jgard...@jonathangardner.net wrote:
  On Feb 17, 12:02 am, Lawrence D'Oliveiro l...@geek-
  central.gen.new_zealand wrote:
  In message
  8ca440b2-6094-4b35-80c5-81d000517...@v20g2000prb.googlegroups.com,

  Jonathan Gardner wrote:
   I used to think anonymous functions (AKA blocks, etc...) would be
   a nice feature for Python.

   Then I looked at a stack trace from a different programming
   language with lots of anonymous functions. (I believe it was
   perl.)

  Didn’t it have source line numbers in it?

  What more do you need?

  I don't know, but I tend to find the name of the function I called to
  be useful. It's much more memorable than line numbers, particularly
  when line numbers keep changing.

  I doubt it's just me, though.

 Some problems with using just line numbers to track errors:

 In any language it isn't much use if you get a bug report from a
 shipped program that says there was an error on line 793 but no report
 of exactly which version of the shipped code was being run.

 Microsoft love telling you the line number: if IE gets a Javascript
 error it reports line number but not filename, so you have to guess
 which of the HTML page or one of many included files actually had the
 error. Plus the line number that is reported is often slightly off.

 Javascript in particular is often sent to the browser compressed then
 uncompressed and eval'd. That makes line numbers completely useless for
 tracking down bugs as you'll always get the line number of the eval.
 Also the way functions are defined in Javascript means you'll often
 have almost every function listed in a backtrace as 'Anonymous'.
 
 If this is an argument against using anonymous functions, then it is a
 quadruple strawman.

There really ought to be a special level of Hell for people who misuse 
strawman to mean a weak or invalid argument instead of what it 
actually means, which is a weak or invalid argument NOT HELD by your 
opponent, which you (generic you) made up specifically for the sake of 
shooting down.

If you actually read what Duncan says, he prefixes his response with:

Some problems with using just line numbers to track errors.

Duncan's post is an argument against relying on line numbers as your 
main, or only, source of information about the location of bugs in 
Javascript.

In fact, this post is remarkable for the sheer number of actual strawman 
arguments that you (Steve Howell) use:


 Shipping buggy code is a bad idea, even with named functions.

Strawman #1: nobody said that shipping buggy code was a good idea, with 
or without named functions. But shipping buggy code *happens*, no matter 
how careful you are, so you need to expect bug reports back from users.

(And they will be *hard to find* bugs, because if they were easy to find 
you would have found them in your own testing before shipping.)


 Obscuring line numbers is a bad idea, even with named functions.

Strawman #2: nobody said that obscuring line numbers was a good idea. But 
apparently compressing Javascript is valuable for other reasons, and 
obscuring the line numbers is the side-effect of doing so. 

And even knowing the line numbers is not necessarily useful, because many 
bugs aren't due to the line that raises the stack trace. Just because you 
know the line which failed doesn't mean you know how to fix the bug.


 Having your customers stay on older versions of your software is a bad
 idea, even with named functions.

Strawman #3: nobody said that staying on older versions is a good idea. 
But sometimes it happens whether you like it or not.

(Although I'd like to point out that from the end user's perspective, 
sometimes we don't want your stinkin' new version with all the anti-
features and pessimations and will stick to the old version for as long 
as possible. If you don't like it, then think a bit harder before adding 
anti-features like fragile, easily-corrupted databases which perform 
really, really badly when your home directory is mounted over the 
network. I'm talking to you, Firefox developers.)

And it doesn't really matter: you either end-of-life the old version, in 
which case you don't need to do anything about the bug report except say 
upgrade, or you decide to continue support, in which case it doesn't 
matter whether the bug is reported for an old version or the latest 
version, you still need to fix it.


 Not being able to know which version of software you're customer is
 running is a bad idea, even with named functions.

Strawman #4. 

See the pattern? When you attack a position the other guy hasn't taken, 
that's a strawman. When you make a weak argument, it's just a weak 
argument.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Jonathan Gardner
On Feb 18, 8:15 am, Steve Howell showel...@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
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steven D'Aprano
On Thu, 18 Feb 2010 08:15:46 -0800, Steve Howell wrote:

 Just to be clear, I'm not saying it's unforgivable to occasionally ship
 software with bugs.  It happens.

Occasionally? Oh, if only.

I would say that there probably isn't a non-trivial application in the 
world that is entirely bug-free. If you're shipping something more 
complex than the proverbial Hello World, chances are high that there 
will be bugs, and the more complex the app, the more bugs are likely.


 Compressing Javascript is sometimes necessary, but I believe that often
 mangles named functions too.

It doesn't mangle the function, it mangles reporting of line numbers. But 
if you know the name of the function, it is much easier to recover from 
that loss of information.

 
 To the the extent that your customer is running old software and cannot
 always coherently describe tracebacks over a telephone, that problem can
 be solved in the software itself, assuming an Internet connection.  The
 software can capture the traceback and report back to a server with the
 version number.

I don't understand why you repeatedly mention old software. It is 
irrelevant: the software is either supported, or not supported. If it's 
not supported, you don't care about the bugs. If it is supported, then it 
doesn't matter whether it is version 2.2 or 2.3 or the bleeding edge 2.4-
pre-alpha straight out of subversion, you still have to go through the 
same process of finding the bug, solving it, then rolling the fix out to 
all supported versions where the bug applies.

That's not to say that the version number isn't useful information to 
have, because it can be, but distinguishing between old versions and the 
current version isn't a useful distinction. In a sense, there are no old 
versions, there are merely multiple supported current versions.

 So, much of the argument against anonymous functions presented so far is
 really orthogonal to whether functions are named or not.

Not so. The point is that anonymous functions lack useful information, 
namely the function name. Because line numbers can be unreliable or even 
missing completely, and even when reliable many people have a mental 
blind-spot for them (I know I do, and I'm gratified to see I'm not the 
only one), lacking a good name for the function is a handicap. Not 
necessarily an insurmountable one, but anonymous functions are more 
troublesome than named functions.

You wouldn't name your functions:

f01, f02, f03, f04, ... f99

(say), unless you were trying to deliberately obfuscate your code. 
Anonymous functions are even more obfuscated than that. You can get away 
with it so long as you're only dealing with a few, in well-defined 
placed, but you wouldn't want to use them all over the place.

-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread sjdevn...@yahoo.com
On Feb 18, 11:15 am, Steve Howell showel...@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

 IMHO there is no reason that I should have to name the content of each
 of those four blocks of code, nor should I have to introduce the
 lambda keyword.

You could do it without intermediate names or lambdas in Python as:
def print_numbers():
for i in [ cube for (square, cube) in
 [(n*n, n*n*n) for n in [1,2,3,4,5,6]]
   if square!=25 and cube!=64 ]:
print i

But frankly, although there's no reason that you _have_ to name the
content at each step, I find it a lot more readable if you do:

def print_numbers():
tuples = [(n*n, n*n*n) for n in (1,2,3,4,5,6)]
filtered = [ cube for (square, cube) in tuples if square!=25 and
cube!=64 ]
for f in filtered:
print f
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread John Bokma
Jonathan Gardner jgard...@jonathangardner.net writes:

 On Feb 18, 8:15 am, Steve Howell showel...@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):

   ^ should be 7

But for the rest, I agree with you. I can read Steve's version, but even
to an experienced Perl programmer that looks quite noisy :-)

-- 
John Bokma   j3b

Hacking  Hiking in Mexico -  http://johnbokma.com/
http://castleamber.com/ - Perl  Python Development
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread John Bokma
John Bokma j...@castleamber.com writes:

 Jonathan Gardner jgard...@jonathangardner.net writes:

 On Feb 18, 8:15 am, Steve Howell showel...@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):

^ should be 7

 But for the rest, I agree with you. I can read Steve's version, but even
 to an experienced Perl programmer that looks quite noisy :-)

Oh, wait, it's Ruby :-D.

-- 
John Bokma   j3b

Hacking  Hiking in Mexico -  http://johnbokma.com/
http://castleamber.com/ - Perl  Python Development
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Jonathan Gardner
On Feb 18, 3:04 pm, sjdevn...@yahoo.com sjdevn...@yahoo.com wrote:

 You could do it without intermediate names or lambdas in Python as:
 def print_numbers():
     for i in [ cube for (square, cube) in
                          [(n*n, n*n*n) for n in [1,2,3,4,5,6]]
                if square!=25 and cube!=64 ]:
         print i

 But frankly, although there's no reason that you _have_ to name the
 content at each step, I find it a lot more readable if you do:

 def print_numbers():
     tuples = [(n*n, n*n*n) for n in (1,2,3,4,5,6)]
     filtered = [ cube for (square, cube) in tuples if square!=25 and
 cube!=64 ]
     for f in filtered:
         print f

Step away from the keyboard! This is a programmer's arrest!

There are laws around here, laws that we can't allow to be broken.
You've just broken 12 of them. You think the laws don't apply to you,
huh, punk? HUH?

I'm sentencing you to three months HARD LABOR in Ruby for that code
you just wrote. And if you think it's too harsh, then I'll sentence
you to NINE MONTHS PHP and see how you feel about that!

;-)
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steve Howell
On Feb 18, 3:00 pm, Steven D'Aprano st...@remove-this-
cybersource.com.au wrote:
 [...]
 You wouldn't name your functions:

 f01, f02, f03, f04, ... f99


Exactly.

 (say), unless you were trying to deliberately obfuscate your code.
 Anonymous functions are even more obfuscated than that. You can get away
 with it so long as you're only dealing with a few, in well-defined
 placed, but you wouldn't want to use them all over the place.


I have contributed to the confusion of this discussion by talking
about anonymous functions, when the original context was anonymous
blocks.  As I mentioned in an earlier response, most anonymous blocks
in Ruby are placed within outer functions, so they're not that hard to
locate in a traceback that provides only function names.  And, of
course, it is often the case that you host Ruby code on your own web
server, or that you distribute Ruby code without compressing it, in
which case you get a sane traceback that provides line numbers.

You actually use anonymous blocks in your own code, in a few, well-
defined places (generally loops).

These excerpts are taken from obfuscate.py:

quotient = a//mm
a, mm = mm, a%mm
xx, x = x - quotient*xx, xx
yy, y = y - quotient*yy, yy


rail = it.next()  # The rail we add to.
assert 0 = rail  rails
fence[rail].append(c)


# Save one non-chaff character.
buffer.append(msg.next())
# And toss away more chaff.
n = self.hash(key) % factor
key = self.mod_key(key)
self.get_chars(n, msg)


# Careful here! Not all classes have a __dict__!
adict = getattr(obj, '__dict__', {})
for name, attr in adict.items():
if inspect.ismethoddescriptor(attr):
d[nm + '.' + name] = attr.__get__(obj)

If any of the above code were to fail on a customer site, you'd
probably want to get line numbers in a traceback.  I'm guessing you
probably don't distribute your code in compressed form, and you
probably take care to make sure it works right in the first place, and
you probably have source control to help you pull up old versions of
your code.  I notice that you even have a __version__ identifier in
your source code, which users of your library could capture in their
tracebacks.  In other words, you probably use mostly the same
practices that I use, except that we seem to differ on the utility or
expressiveness or Ruby blocks, or maybe we're arguing at cross
purposes.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steve Holden
Steven D'Aprano wrote:
 On Thu, 18 Feb 2010 06:15:20 -0800, Steve Howell wrote:
[...]
 There really ought to be a special level of Hell for people who misuse 
 strawman to mean a weak or invalid argument instead of what it 
 actually means, which is a weak or invalid argument NOT HELD by your 
 opponent, which you (generic you) made up specifically for the sake of 
 shooting down.
 
 If you actually read what Duncan says, he prefixes his response with:
 
 Some problems with using just line numbers to track errors.
 
 Duncan's post is an argument against relying on line numbers as your 
 main, or only, source of information about the location of bugs in 
 Javascript.
 
 In fact, this post is remarkable for the sheer number of actual strawman 
 arguments that you (Steve Howell) use:
 
 
 Shipping buggy code is a bad idea, even with named functions.
 
 Strawman #1: nobody said that shipping buggy code was a good idea, with 
 or without named functions. But shipping buggy code *happens*, no matter 
 how careful you are, so you need to expect bug reports back from users.
 
 (And they will be *hard to find* bugs, because if they were easy to find 
 you would have found them in your own testing before shipping.)
 
 
 Obscuring line numbers is a bad idea, even with named functions.
 
 Strawman #2: nobody said that obscuring line numbers was a good idea. But 
 apparently compressing Javascript is valuable for other reasons, and 
 obscuring the line numbers is the side-effect of doing so. 
 
 And even knowing the line numbers is not necessarily useful, because many 
 bugs aren't due to the line that raises the stack trace. Just because you 
 know the line which failed doesn't mean you know how to fix the bug.
 
 
 Having your customers stay on older versions of your software is a bad
 idea, even with named functions.
 
 Strawman #3: nobody said that staying on older versions is a good idea. 
 But sometimes it happens whether you like it or not.
 
 (Although I'd like to point out that from the end user's perspective, 
 sometimes we don't want your stinkin' new version with all the anti-
 features and pessimations and will stick to the old version for as long 
 as possible. If you don't like it, then think a bit harder before adding 
 anti-features like fragile, easily-corrupted databases which perform 
 really, really badly when your home directory is mounted over the 
 network. I'm talking to you, Firefox developers.)
 
 And it doesn't really matter: you either end-of-life the old version, in 
 which case you don't need to do anything about the bug report except say 
 upgrade, or you decide to continue support, in which case it doesn't 
 matter whether the bug is reported for an old version or the latest 
 version, you still need to fix it.
 
 
 Not being able to know which version of software you're customer is
 running is a bad idea, even with named functions.
 
 Strawman #4. 
 
 See the pattern? When you attack a position the other guy hasn't taken, 
 that's a strawman. When you make a weak argument, it's just a weak 
 argument.
 
Next week: Lesson 2 - Ad Hominem Attacks

regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
PyCon is coming! Atlanta, Feb 2010  http://us.pycon.org/
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS:http://holdenweb.eventbrite.com/

-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steve Howell
On Feb 18, 3:04 pm, sjdevn...@yahoo.com sjdevn...@yahoo.com wrote:
 On Feb 18, 11:15 am, Steve Howell showel...@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

  IMHO there is no reason that I should have to name the content of each
  of those four blocks of code, nor should I have to introduce the
  lambda keyword.

 You could do it without intermediate names or lambdas in Python as:
 def print_numbers():
     for i in [ cube for (square, cube) in
                          [(n*n, n*n*n) for n in [1,2,3,4,5,6]]
                if square!=25 and cube!=64 ]:
         print i


The problem with list comprehensions is that they read kind of out of
order.  On line 2 you are doing the first operation, then on line 3
you are filtering, then on line 1 your are selecting, then on line 4
you are printing.

For such a small example, your code is still quite readable.

 But frankly, although there's no reason that you _have_ to name the
 content at each step, I find it a lot more readable if you do:

 def print_numbers():
     tuples = [(n*n, n*n*n) for n in (1,2,3,4,5,6)]
     filtered = [ cube for (square, cube) in tuples if square!=25 and
 cube!=64 ]
     for f in filtered:
         print f

The names you give to the intermediate results here are
terse--tuples and filtered--so your code reads nicely.

In a more real world example, the intermediate results would be
something like this:

   departments
   departments_in_new_york
   departments_in_new_york_not_on_bonus_cycle
   employees_in_departments_in_new_york_not_on_bonus_cycle
   names_of_employee_in_departments_in_new_york_not_on_bonus_cycle

-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Paul Rubin
Steve Howell showel...@yahoo.com writes:

 But frankly, although there's no reason that you _have_ to name the
 content at each step, I find it a lot more readable if you do:

 def print_numbers():
     tuples = [(n*n, n*n*n) for n in (1,2,3,4,5,6)]
     filtered = [ cube for (square, cube) in tuples if square!=25 and
 cube!=64 ]
     for f in filtered:
         print f

 The names you give to the intermediate results here are
 terse--tuples and filtered--so your code reads nicely.

But that example makes tuples and filtered into completely expanded
lists in memory.  I don't know Ruby so I've been wondering whether the
Ruby code would run as an iterator pipeline that uses constant memory.

 In a more real world example, the intermediate results would be
 something like this:

departments
departments_in_new_york
departments_in_new_york_not_on_bonus_cycle
employees_in_departments_in_new_york_not_on_bonus_cycle
names_of_employee_in_departments_in_new_york_not_on_bonus_cycle

http://haskell.org/ghc/docs/6.10.4/html/users_guide/syntax-extns.html#generalised-list-comprehensions

might be of interest.  Maybe Ruby and/or Python could grow something similar.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread sjdevn...@yahoo.com
On Feb 18, 10:58 pm, Paul Rubin no.em...@nospam.invalid wrote:
 Steve Howell showel...@yahoo.com writes:
  But frankly, although there's no reason that you _have_ to name the
  content at each step, I find it a lot more readable if you do:

  def print_numbers():
      tuples = [(n*n, n*n*n) for n in (1,2,3,4,5,6)]
      filtered = [ cube for (square, cube) in tuples if square!=25 and
  cube!=64 ]
      for f in filtered:
          print f

  The names you give to the intermediate results here are
  terse--tuples and filtered--so your code reads nicely.

 But that example makes tuples and filtered into completely expanded
 lists in memory.  I don't know Ruby so I've been wondering whether the
 Ruby code would run as an iterator pipeline that uses constant memory.

I don't know how Ruby works, either.  If it's using constant memory,
switching the Python to generator comprehensions (and getting constant
memory usage) is simply a matter of turning square brackets into
parentheses:

def print_numbers():
tuples = ((n*n, n*n*n) for n in (1,2,3,4,5,6))
filtered = ( cube for (square, cube) in tuples if square!=25 and
 cube!=64 )
for f in filtered:
print f

Replace (1,2,3,4,5,6) with xrange(1) and memory usage still
stays constant.

Though for this particular example, I prefer a strict looping solution
akin to what Jonathan Gardner had upthread:

for n in (1,2,3,4,5,6):
square = n*n
cube = n*n*n
if square == 25 or cube == 64: continue
print cube

  In a more real world example, the intermediate results would be
  something like this:

     departments
     departments_in_new_york
     departments_in_new_york_not_on_bonus_cycle
     employees_in_departments_in_new_york_not_on_bonus_cycle
     names_of_employee_in_departments_in_new_york_not_on_bonus_cycle

I don't think the assertion that the names would be ridiculously long
is accurate, either.

Something like:

departments = blah
ny_depts = blah(departments)
non_bonus_depts = blah(ny_depts)
non_bonus_employees = blah(non_bonus_depts)
employee_names = blah(non_bonus_employees)

If the code is at all well-structured, it'll be just as obvious from
the context that each list/generator/whatever is building from the
previous one as it is in the anonymous block case.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steve Howell
On Feb 18, 2:49 pm, Jonathan Gardner jgard...@jonathangardner.net
wrote:
 On Feb 18, 8:15 am, Steve Howell showel...@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


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

2010-02-18 Thread Steve Howell
On Feb 18, 7:58 pm, Paul Rubin no.em...@nospam.invalid wrote:
 Steve Howell showel...@yahoo.com writes:
  But frankly, although there's no reason that you _have_ to name the
  content at each step, I find it a lot more readable if you do:

  def print_numbers():
      tuples = [(n*n, n*n*n) for n in (1,2,3,4,5,6)]
      filtered = [ cube for (square, cube) in tuples if square!=25 and
  cube!=64 ]
      for f in filtered:
          print f

  The names you give to the intermediate results here are
  terse--tuples and filtered--so your code reads nicely.

 But that example makes tuples and filtered into completely expanded
 lists in memory.  I don't know Ruby so I've been wondering whether the
 Ruby code would run as an iterator pipeline that uses constant memory.


That's a really good question.  I don't know the answer.  My hunch is
that you could implement generators using Ruby syntax, but it's
probably not implemented that way.

The fact that Python allows you to turn the intermediate results into
generator expressions is a very powerful feature, of course.

  In a more real world example, the intermediate results would be
  something like this:

     departments
     departments_in_new_york
     departments_in_new_york_not_on_bonus_cycle
     employees_in_departments_in_new_york_not_on_bonus_cycle
     names_of_employee_in_departments_in_new_york_not_on_bonus_cycle

 http://haskell.org/ghc/docs/6.10.4/html/users_guide/syntax-extns.html...

 might be of interest.  Maybe Ruby and/or Python could grow something similar.

Can you elaborate?

-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steve Howell
On Feb 18, 8:27 pm, sjdevn...@yahoo.com sjdevn...@yahoo.com wrote:
 On Feb 18, 10:58 pm, Paul Rubin no.em...@nospam.invalid wrote:

  Steve Howell showel...@yahoo.com writes:
   But frankly, although there's no reason that you _have_ to name the
   content at each step, I find it a lot more readable if you do:

   def print_numbers():
       tuples = [(n*n, n*n*n) for n in (1,2,3,4,5,6)]
       filtered = [ cube for (square, cube) in tuples if square!=25 and
   cube!=64 ]
       for f in filtered:
           print f

   The names you give to the intermediate results here are
   terse--tuples and filtered--so your code reads nicely.

  But that example makes tuples and filtered into completely expanded
  lists in memory.  I don't know Ruby so I've been wondering whether the
  Ruby code would run as an iterator pipeline that uses constant memory.

 I don't know how Ruby works, either.  If it's using constant memory,
 switching the Python to generator comprehensions (and getting constant
 memory usage) is simply a matter of turning square brackets into
 parentheses:

 def print_numbers():
     tuples = ((n*n, n*n*n) for n in (1,2,3,4,5,6))
     filtered = ( cube for (square, cube) in tuples if square!=25 and
                  cube!=64 )
     for f in filtered:
         print f

 Replace (1,2,3,4,5,6) with xrange(1) and memory usage still
 stays constant.

 Though for this particular example, I prefer a strict looping solution
 akin to what Jonathan Gardner had upthread:

 for n in (1,2,3,4,5,6):
     square = n*n
     cube = n*n*n
     if square == 25 or cube == 64: continue
     print cube

   In a more real world example, the intermediate results would be
   something like this:

      departments
      departments_in_new_york
      departments_in_new_york_not_on_bonus_cycle
      employees_in_departments_in_new_york_not_on_bonus_cycle
      names_of_employee_in_departments_in_new_york_not_on_bonus_cycle

 I don't think the assertion that the names would be ridiculously long
 is accurate, either.

 Something like:

 departments = blah
 ny_depts = blah(departments)
 non_bonus_depts = blah(ny_depts)
 non_bonus_employees = blah(non_bonus_depts)
 employee_names = blah(non_bonus_employees)

 If the code is at all well-structured, it'll be just as obvious from
 the context that each list/generator/whatever is building from the
 previous one as it is in the anonymous block case.

I agree that the names don't have to be as ridiculously long as my
examples, but using intermediate locals forces you to come up with
consistent abbreviations between adjacent lines, which adds to the
maintenance burden.  When the requirements change so that bonuses
apply to NY and PA departments, you would have to change three places
in the code instead of one.

To the extent that each of your transformations were named functions,
you'd need to maintain the names there as well (something more
descriptive than blah).


-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Kurt Smith
On Thu, Feb 18, 2010 at 10:46 PM, Steve Howell showel...@yahoo.com wrote:
 On Feb 18, 2:49 pm, Jonathan Gardner jgard...@jonathangardner.net
 wrote:
 On Feb 18, 8:15 am, Steve Howell showel...@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-
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steve Howell
On Feb 18, 7:58 pm, Paul Rubin no.em...@nospam.invalid wrote:
 Steve Howell showel...@yahoo.com writes:
  But frankly, although there's no reason that you _have_ to name the
  content at each step, I find it a lot more readable if you do:

  def print_numbers():
      tuples = [(n*n, n*n*n) for n in (1,2,3,4,5,6)]
      filtered = [ cube for (square, cube) in tuples if square!=25 and
  cube!=64 ]
      for f in filtered:
          print f

  The names you give to the intermediate results here are
  terse--tuples and filtered--so your code reads nicely.

 But that example makes tuples and filtered into completely expanded
 lists in memory.  I don't know Ruby so I've been wondering whether the
 Ruby code would run as an iterator pipeline that uses constant memory.


Running the following code would probably answer your question.  At
least in the case of Array.map and Array.reject, under my version of
Ruby, each block transforms the entire array before passing control to
the next block.

def print_numbers()
[1, 2, 3, 4, 5, 6].map { |n|
puts 'first block', n
[n * n, n * n * n]
}.reject { |square, cube|
puts 'reject', square
square == 25 || cube == 64
}.map { |square, cube|
cube
}.each { |cube|
puts cube
}
end

print_numbers()

But I'm running only version 1.8.7.  Version 1.9 of Ruby apparently
introduced something more akin to generators and Unix pipelines:

http://pragdave.blogs.pragprog.com/pragdave/2007/12/pipelines-using.html

I haven't tried them myself.


-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Paul Rubin
Steve Howell showel...@yahoo.com writes:
 http://haskell.org/ghc/docs/6.10.4/html/users_guide/syntax-extns.html...
 might be of interest.  Maybe Ruby and/or Python could grow something similar.
 Can you elaborate?

List comprehensions are a Python feature you're probably familiar with,
and I think Ruby has something like them too.  They originally came from
Haskell.  GHC (the main Haskell implementation) now supports an extended
list comprehension syntax with SQL-like features.  I haven't used it
much yet, but here's an example from a poker ranking program
(http://www.rubyquiz.com/quiz24.html) that I did as a Haskell exercise:

  let (winners:others) = 
[zip c ls | ls - lines cs
, let {h = mkHand ls; c=classify h}
, then group by c
, then sortWith by Down c]

It's reasonably evocative and doing the same thing with the older
syntax would have been a big mess.  Down basically means sort
in reverse order.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steven D'Aprano
On Thu, 18 Feb 2010 22:48:21 -0500, Steve Holden wrote:

 Next week: Lesson 2 - Ad Hominem Attacks

I wouldn't pay any attention to Steve, all Stevens are notorious liars.

-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Gregory Ewing

Steve Howell wrote:


Python may not support the broadest notion of anonymous functions, but
it definitely has anonymous blocks.  You can write this in Python:

for i in range(10):
print i
print i * i
print i * i * i


There's a clear difference between this and a Ruby block,
however. A block in Ruby is implemented by passing a
callable object to a method. There is no callable object
corresponding to the body of a for-loop in Python.

The important thing about Ruby blocks is not that they're
anonymous, but that they're concrete objects that can
be manipulated.

The Ruby approach has the advantage of making it possible
to implement user-defined control structures without
requiring a macro facility. You can't do that in Python.

However, there's something that Python's iterator protocol
makes possible that you can't do with a block-passing
approach. You can have multiple iterators active at once,
and pull values from them as an when required in the
calling code. Ruby's version of the iterator protocol
can't handle that, because once an iterator is started
it retains control until it's finished.

Also, most people who advocate adding some form of
block-passing facility to Python don't seem to have
thought through what would happen if the block contains
any break, continue, return or yield statements.

This issue was looked into in some detail back when there
was consideration of implementing the with-statement
by passing the body as a function. Getting these
statements to behave intuitively inside the body
turned out to be a very thorny problem -- thorny enough
to cause the block-passing idea to be abandoned in
favour of the current implementation.

--
Greg
--
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steven D'Aprano
On Thu, 18 Feb 2010 19:57:35 -0800, Steve Howell wrote:

 The names you give to the intermediate results here are terse--tuples
 and filtered--so your code reads nicely.
 
 In a more real world example, the intermediate results would be
 something like this:
 
departments
departments_in_new_york
departments_in_new_york_not_on_bonus_cycle
employees_in_departments_in_new_york_not_on_bonus_cycle
names_of_employee_in_departments_in_new_york_not_on_bonus_cycle

Those last two could be written more concisely as:

serfs_in_new_york
names_of_serfs_in_new_york_as_if_we_cared

But seriously... if you have a variable called departments_in_new_york, 
presumably you also have variables called departments_in_washington, 
departments_in_los_angeles, departments_in_houston, 
departments_in_walla_walla, and so forth. If so, this is a good sign 
that you are doing it wrong and you need to rethink your algorithm.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steve Howell
On Feb 18, 9:41 pm, Steven D'Aprano st...@remove-this-
cybersource.com.au wrote:
 On Thu, 18 Feb 2010 22:48:21 -0500, Steve Holden wrote:
  Next week: Lesson 2 - Ad Hominem Attacks

 I wouldn't pay any attention to Steve, all Stevens are notorious liars.

 --
 Steven

Especially when their last name starts with H.

Cheers,

Steve

-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steven D'Aprano
On Fri, 19 Feb 2010 18:52:20 +1300, Gregory Ewing wrote:

 The Ruby approach has the advantage of making it possible to implement
 user-defined control structures without requiring a macro facility. You
 can't do that in Python.
[...] 
 Also, most people who advocate adding some form of block-passing
 facility to Python don't seem to have thought through what would happen
 if the block contains any break, continue, return or yield statements.

That is the only time I ever wanted blocks: I had a series of functions 
containing for loops that looked something vaguely like this:

for x in sequence:
code_A
try:
something
except some_exception:
code_B

where code_B was different in each function, so I wanted to pull it out 
as a code block and do this:


def common_loop(x, block):
code_A
try:
something
except some_exception:
block

for x in sequence:
common_loop(x, block)


The problem was that the blocks contained a continue statement, so I was 
stymied.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steve Howell
On Feb 18, 9:46 pm, Steven D'Aprano st...@remove-this-
cybersource.com.au wrote:
 On Thu, 18 Feb 2010 19:57:35 -0800, Steve Howell wrote:
  The names you give to the intermediate results here are terse--tuples
  and filtered--so your code reads nicely.

  In a more real world example, the intermediate results would be
  something like this:

     departments
     departments_in_new_york
     departments_in_new_york_not_on_bonus_cycle
     employees_in_departments_in_new_york_not_on_bonus_cycle
     names_of_employee_in_departments_in_new_york_not_on_bonus_cycle

 Those last two could be written more concisely as:

 serfs_in_new_york
 names_of_serfs_in_new_york_as_if_we_cared

 But seriously... if you have a variable called departments_in_new_york,
 presumably you also have variables called departments_in_washington,
 departments_in_los_angeles, departments_in_houston,
 departments_in_walla_walla, and so forth. If so, this is a good sign
 that you are doing it wrong and you need to rethink your algorithm.


Sure, but it could also be that you're launching a feature that is
only temporarily limited to New York departments, and any investment
in coming up with names for the New York filter function or
intermediate local variables becomes pointless once you go national:

# version 1
emps = [
['Bob Rich', 'NY', 55],
['Alice Serf', 'NY', 30],
['Joe Peasant', 'MD', 12],
['Mary Pauper', 'CA', 13],
]

emps.select { |name, state, salary|
salary  40
}.select { |name, state, salary|
# limit bonuses to NY for now...reqs
# may change!
state == 'NY'
}.each { |name, state, salary|
new_salary = salary * 1.1
puts #{name} gets a raise to #{new_salary}!
}

# version 2
emps = [
['Bob Rich', 'NY', 55],
['Alice Serf', 'NY', 30],
['Joe Peasant', 'MD', 12],
['Mary Pauper', 'CA', 13],
]

emps.select { |name, state, salary|
salary  40
}.each { |name, state, salary|
new_salary = salary * 1.1
puts #{name} gets a raise to #{new_salary}!
}

-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steve Howell
On Feb 18, 9:37 pm, Kurt Smith kwmsm...@gmail.com wrote:
 On Thu, Feb 18, 2010 at 10:46 PM, Steve Howell showel...@yahoo.com wrote:
  On Feb 18, 2:49 pm, Jonathan Gardner jgard...@jonathangardner.net
  wrote:
  On Feb 18, 8:15 am, Steve Howell showel...@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.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-18 Thread Steve Howell
On Feb 18, 9:52 pm, Gregory Ewing greg.ew...@canterbury.ac.nz wrote:
 Steve Howell wrote:
  Python may not support the broadest notion of anonymous functions, but
  it definitely has anonymous blocks.  You can write this in Python:

      for i in range(10):
          print i
          print i * i
          print i * i * i

 There's a clear difference between this and a Ruby block,
 however. A block in Ruby is implemented by passing a
 callable object to a method. There is no callable object
 corresponding to the body of a for-loop in Python.

 The important thing about Ruby blocks is not that they're
 anonymous, but that they're concrete objects that can
 be manipulated.


Agreed.

 The Ruby approach has the advantage of making it possible
 to implement user-defined control structures without
 requiring a macro facility. You can't do that in Python.

 However, there's something that Python's iterator protocol
 makes possible that you can't do with a block-passing
 approach. You can have multiple iterators active at once,
 and pull values from them as an when required in the
 calling code. Ruby's version of the iterator protocol
 can't handle that, because once an iterator is started
 it retains control until it's finished.


Is this still true or Ruby today?

http://pragdave.blogs.pragprog.com/pragdave/2007/12/pipelines-using.html

 Also, most people who advocate adding some form of
 block-passing facility to Python don't seem to have
 thought through what would happen if the block contains
 any break, continue, return or yield statements.


For sure.  It's certainly not clear to me how Ruby handles all those
cases, although I am still quite new to Ruby, so it's possible that I
just haven't stumbled upon the best explanations yet.

 This issue was looked into in some detail back when there
 was consideration of implementing the with-statement
 by passing the body as a function. Getting these
 statements to behave intuitively inside the body
 turned out to be a very thorny problem -- thorny enough
 to cause the block-passing idea to be abandoned in
 favour of the current implementation.


I found these links in the archive...were these part of the discussion
you were referring to?

http://mail.python.org/pipermail/python-dev/2005-April/052907.html

http://mail.python.org/pipermail/python-dev/2005-April/053055.html

http://mail.python.org/pipermail/python-dev/2005-April/053123.html

-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Lawrence D'Oliveiro
In message 60b1abce-4381-46ab-91ed-
f2ab2154c...@g19g2000yqe.googlegroups.com, Andrej Mitrovic wrote:

 Also, lambda's are expressions, not statements ...

Is such a distinction Pythonic, or not? For example, does Python distinguish 
between functions and procedures?
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Lawrence D'Oliveiro
In message 
8ca440b2-6094-4b35-80c5-81d000517...@v20g2000prb.googlegroups.com, 
Jonathan Gardner wrote:

 I used to think anonymous functions (AKA blocks, etc...) would be a
 nice feature for Python.
 
 Then I looked at a stack trace from a different programming language
 with lots of anonymous functions. (I believe it was perl.)

Didn’t it have source line numbers in it?

What more do you need?
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Bruno Desthuilliers

Aahz a écrit :

In article 8ca440b2-6094-4b35-80c5-81d000517...@v20g2000prb.googlegroups.com,
Jonathan Gardner  jgard...@jonathangardner.net wrote:

I used to think anonymous functions (AKA blocks, etc...) would be a
nice feature for Python.

Then I looked at a stack trace from a different programming language
with lots of anonymous functions. (I believe it was perl.)

I became enlightened.


+1 QOTW


++1 QOTW !-)

Had the same problem trying to debug some javascript...
--
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread John Bokma
Jonathan Gardner jgard...@jonathangardner.net writes:

 Then I looked at a stack trace from a different programming language
 with lots of anonymous functions. (I believe it was perl.)

 I became enlightened.

If it was Perl [1], I doubt it. Because line numbers are reported, and
if that doesn't help you, you can annotate anonymous functions with a
nick name using

local *__ANON__ = 'nice name';

Finding an issue, and not looking for a solution is not called becoming
enlightened ;-)


~$ perl -e '
use Carp;

my $anon = sub { local *__ANON__ = hello, world; croak oops; };
$anon-();
'

oops at -e line 4
main::hello, world() called at -e line 5

As you can see, and a line number is generated, and the nice name is
shown.

If you generate anonymouse functions on the fly based on parameters, you
can encode this into the nice name, of course.

Sadly, often bold statements about a language are made in ignorance.


[1] perl is the program that executes Perl programs ;-).

-- 
John Bokma   j3b

Hacking  Hiking in Mexico -  http://johnbokma.com/
http://castleamber.com/ - Perl  Python Development
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread cjw

On 17-Feb-10 05:48 AM, Bruno Desthuilliers wrote:

Lawrence D'Oliveiro a écrit :

In message 60b1abce-4381-46ab-91ed-
f2ab2154c...@g19g2000yqe.googlegroups.com, Andrej Mitrovic wrote:


Also, lambda's are expressions, not statements ...


Is such a distinction Pythonic, or not?


Python is (by design) a statement-based language, so yes, this
distinction is pythonic !-)

Aren't lambda forms better described as function?

Colin W.
--
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Terry Reedy

On 2/17/2010 1:51 PM, cjw wrote:

On 17-Feb-10 05:48 AM, Bruno Desthuilliers wrote:

Lawrence D'Oliveiro a écrit :

In message 60b1abce-4381-46ab-91ed-
f2ab2154c...@g19g2000yqe.googlegroups.com, Andrej Mitrovic wrote:


Also, lambda's are expressions, not statements ...


Is such a distinction Pythonic, or not?


Python is (by design) a statement-based language, so yes, this
distinction is pythonic !-)

Aren't lambda forms better described as function?


They are expressions that evaluate to function objects nearly identical 
to that produced by the def statememt they abbreviate. The only 
difference is the .__name__ attribute.


Terry Jan Reedy




--
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Lawrence D'Oliveiro
In message hlhdsi$2p...@theodyn.ncf.ca, cjw wrote:

 Aren't lambda forms better described as function?

Is this a function?

lambda : None

What about this?

lambda : sys.stdout.write(hi there!\n)

-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Terry Reedy

On 2/17/2010 5:46 PM, Lawrence D'Oliveiro wrote:

In messagehlhdsi$2p...@theodyn.ncf.ca, cjw wrote:


Aren't lambda forms better described as function?


Is this a function?

 lambda : None

What about this?

 lambda : sys.stdout.write(hi there!\n)


To repeat: Python lambda expressions evaluate to function objects 
identical, except for .__name__ attribute, to the equivalent def statememnt.


 type(lambda:None)
class 'function'
 import sys
 type(lambda : sys.stdout.write(hi there!\n))
class 'function'



--
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Ben Finney
Lawrence D'Oliveiro l...@geek-central.gen.new_zealand writes:

 In message hlhdsi$2p...@theodyn.ncf.ca, cjw wrote:

  Aren't lambda forms better described as function?

 Is this a function?

 lambda : None

 What about this?

 lambda : sys.stdout.write(hi there!\n)

They are both lambda forms in Python. As a Python expression, they
evaluate to (they “return”) a function object.

-- 
 \   “It is wrong to think that the task of physics is to find out |
  `\ how nature *is*. Physics concerns what we can *say* about |
_o__) nature…” —Niels Bohr |
Ben Finney
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Steven D'Aprano
On Thu, 18 Feb 2010 11:46:52 +1300, Lawrence D'Oliveiro wrote:

 In message hlhdsi$2p...@theodyn.ncf.ca, cjw wrote:
 
 Aren't lambda forms better described as function?
 
 Is this a function?
 
 lambda : None
 
 What about this?
 
 lambda : sys.stdout.write(hi there!\n)

Of course they are; the first is a function that takes no arguments and 
returns None, and the second is a function that takes no arguments, 
returns None, and has a side-effect of writing hi there\n to stout. 

But I imagine you already know that, so I'm not really sure I understand 
the point of your (rhetorical?) question.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Jonathan Gardner
On Feb 17, 10:39 am, John Bokma j...@castleamber.com wrote:
 Jonathan Gardner jgard...@jonathangardner.net writes:
  Then I looked at a stack trace from a different programming language
  with lots of anonymous functions. (I believe it was perl.)

  I became enlightened.

 If it was Perl [1], I doubt it. Because line numbers are reported, and
 if that doesn't help you, you can annotate anonymous functions with a
 nick name using

 local *__ANON__ = 'nice name';

 Finding an issue, and not looking for a solution is not called becoming
 enlightened ;-)

 ~$ perl -e '
 use Carp;

 my $anon = sub { local *__ANON__ = hello, world; croak oops; };
 $anon-();
 '

 oops at -e line 4
         main::hello, world() called at -e line 5

 As you can see, and a line number is generated, and the nice name is
 shown.

 If you generate anonymouse functions on the fly based on parameters, you
 can encode this into the nice name, of course.

 Sadly, often bold statements about a language are made in ignorance.


$ perl -e '$a = sub () {die it may have been javascript, but}; $b =
sub () {die I am pretty sure it was perl}; $b-()'
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Jonathan Gardner
On Feb 17, 12:02 am, Lawrence D'Oliveiro l...@geek-
central.gen.new_zealand wrote:
 In message
 8ca440b2-6094-4b35-80c5-81d000517...@v20g2000prb.googlegroups.com,

 Jonathan Gardner wrote:
  I used to think anonymous functions (AKA blocks, etc...) would be a
  nice feature for Python.

  Then I looked at a stack trace from a different programming language
  with lots of anonymous functions. (I believe it was perl.)

 Didn’t it have source line numbers in it?

 What more do you need?

I don't know, but I tend to find the name of the function I called to
be useful. It's much more memorable than line numbers, particularly
when line numbers keep changing.

I doubt it's just me, though.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Jonathan Gardner
On Feb 17, 12:02 am, Lawrence D'Oliveiro l...@geek-
central.gen.new_zealand wrote:
 In message 60b1abce-4381-46ab-91ed-

 f2ab2154c...@g19g2000yqe.googlegroups.com, Andrej Mitrovic wrote:
  Also, lambda's are expressions, not statements ...

 Is such a distinction Pythonic, or not? For example, does Python distinguish
 between functions and procedures?

Not to the programmer, no. Callables are callable, no matter what they
are, and they are all called the same way.

(What the heck is a procedure, anyway? Is this different from a
subroutine, a method, or a block?)
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Steven D'Aprano
On Wed, 17 Feb 2010 12:39:30 -0600, John Bokma wrote:

 Jonathan Gardner jgard...@jonathangardner.net writes:
 
 Then I looked at a stack trace from a different programming language
 with lots of anonymous functions. (I believe it was perl.)

 I became enlightened.
 
 If it was Perl [1], I doubt it. Because line numbers are reported, and
 if that doesn't help you, you can annotate anonymous functions with a
 nick name using
 
 local *__ANON__ = 'nice name';
[...]
 As you can see, and a line number is generated, and the nice name is
 shown.

Given that it has a nice name, what makes it an anonymous function?

It seems to me that Perl effectively has three ways of creating 
functions, one anonymous and two named (even if one syntax for creating a 
named function is almost identical to the syntax for creating an 
anonymous function). Once you annotate a function with a nickname, it's 
no different from giving it a name.

If this is the case, then your answer to anonymous functions are a PITA 
is don't use anonymous functions, which exactly the same answer we'd 
give here in Python land. The only difference is that Perl provides two 
ways of making a named function, and Python only one[1].






[1] Technically, you can make named functions with the new module and a 
bit of work, so Python has two ways too.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Rhodri James
On Thu, 18 Feb 2010 01:04:00 -, Jonathan Gardner  
jgard...@jonathangardner.net wrote:



On Feb 17, 12:02 am, Lawrence D'Oliveiro l...@geek-
central.gen.new_zealand wrote:

In message 60b1abce-4381-46ab-91ed-

f2ab2154c...@g19g2000yqe.googlegroups.com, Andrej Mitrovic wrote:
 Also, lambda's are expressions, not statements ...

Is such a distinction Pythonic, or not? For example, does Python  
distinguish

between functions and procedures?


Not to the programmer, no. Callables are callable, no matter what they
are, and they are all called the same way.

(What the heck is a procedure, anyway? Is this different from a
subroutine, a method, or a block?)


In classic Pascal, a procedure was distinct from a function in that it had  
no return value.  The concept doesn't really apply in Python; there are no  
procedures in that sense, since if a function terminates without supplying  
an explicit return value it returns None.


--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Steven D'Aprano
On Wed, 17 Feb 2010 17:04:00 -0800, Jonathan Gardner wrote:

 (What the heck is a procedure, anyway? Is this different from a
 subroutine, a method, or a block?)

The name is used in Pascal, which probably means it originated from 
Fortran or Algol. 

A subroutine is a generic piece of code which can be re-used by some 
unspecified mechanism (GOSUB in Basic, by calling it in most other 
languages). A function is a subroutine that returns a result, and a 
procedure is a subroutine that doesn't return anything (not even None, or 
the equivalent thereof) and operates entirely by side-effect.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread John Bokma
Steven D'Aprano ste...@remove.this.cybersource.com.au writes:

 On Wed, 17 Feb 2010 12:39:30 -0600, John Bokma wrote:

[..]
 
 If it was Perl [1], I doubt it. Because line numbers are reported, and
 if that doesn't help you, you can annotate anonymous functions with a
 nick name using
 
 local *__ANON__ = 'nice name';
 [...]
 As you can see, and a line number is generated, and the nice name is
 shown.

 Given that it has a nice name, what makes it an anonymous function?

You can't do 

nice name();

It just changes what perl reports.

 If this is the case, then your answer to anonymous functions are a
 PITA 

I don't think anon functions are in general a
PITA. Like with most things, (I) use them in moderation.

 is don't use anonymous functions, which exactly the same answer we'd 
 give here in Python land. The only difference is that Perl provides two 
 ways of making a named function, and Python only one[1].

Note that the local trick doesn't create a named function. There are
other ways of course to create named functions in Perl, e.g.

perl -e '*foo=sub { print hello, world\n }; foo();'

Which can be fun:

perl -e '
sub AUTOLOAD {
my $name = our $AUTOLOAD;
*$AUTOLOAD = sub { local $ = , ; print $name(@_)\n };
goto $AUTOLOAD;
}
foo(40);
bar(hello, world!);
baz(foo(10));'

output:

main::foo(40)
main::bar(hello, world!)
main::foo(10)
main::baz(1)

NB: calling foo 10 returns 1 (return value of print).

-- 
John Bokma   j3b

Hacking  Hiking in Mexico -  http://johnbokma.com/
http://castleamber.com/ - Perl  Python Development
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Steve Howell
On Feb 17, 5:39 pm, Steven D'Aprano
ste...@remove.this.cybersource.com.au wrote:
 On Wed, 17 Feb 2010 17:04:00 -0800, Jonathan Gardner wrote:
  (What the heck is a procedure, anyway? Is this different from a
  subroutine, a method, or a block?)

 The name is used in Pascal, which probably means it originated from
 Fortran or Algol.

 A subroutine is a generic piece of code which can be re-used by some
 unspecified mechanism (GOSUB in Basic, by calling it in most other
 languages). A function is a subroutine that returns a result, and a
 procedure is a subroutine that doesn't return anything (not even None, or
 the equivalent thereof) and operates entirely by side-effect.


Those are useful clarifications, but they are not completely
universal.

Some people make the definition of function more restrictive--if it
has side effects, it is not a function.

Python's definition of a method is also not universal.  In some
circles, method is more akin to Steven's definition of a procedure--it
does not necessarily have to be associated with a class.

It's all very confusing, which is why Pythonistas are typically
adamant about clarifying definitions within Python's context, which is
understandable.  To the extent that we're all talking about one
programming language, we should use the same terms.

A quick Google search does not turn up an official definition of a
Ruby block, although the term block is colloquially used in both
Python and Ruby to refer to a bunch of lines of code executed in a
particular context, like a loop.

Python may not support the broadest notion of anonymous functions, but
it definitely has anonymous blocks.  You can write this in Python:

for i in range(10):
print i
print i * i
print i * i * i

Python does not force you to do this:

def do_stuff(i):
print i
print i * i
print i * i * i
for i in range(10):
do_stuff(i)
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Steve Howell
On Feb 16, 4:19 pm, Jonathan Gardner jgard...@jonathangardner.net
wrote:
 On Feb 16, 11:41 am, Andrej Mitrovic andrej.mitrov...@gmail.com
 wrote:



  On Feb 16, 7:38 pm, Casey Hawthorne caseyhhammer_t...@istar.ca
  wrote:

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

  http://blog.extracheese.org/2010/02/python-vs-ruby-a-battle-to-the-de...
   --
   Regards,
   Casey

  Gary's friend Geoffrey Grosenbach says in his blog post (which Gary
  linked to): Python has no comparable equivalent to Ruby’s do end
  block. Python lambdas are limited to one line and can’t contain
  statements (for, if, def, etc.). Which leaves me wondering, what’s the
  point?

  I'm sorry, lambda's do support if's and for's. Also, lambda's are
  expressions, not statements, but you can pass them around, keep them
  in a dictionary if you want to. And if you need more than one line of
  statements, for crying out loud use a def? And who needs those do-
  end blocks anyway, trying to turn Python into Pascal?

 I used to think anonymous functions (AKA blocks, etc...) would be a
 nice feature for Python.

 Then I looked at a stack trace from a different programming language
 with lots of anonymous functions. (I believe it was perl.)

 I became enlightened.

I use Ruby a lot in my day job, and we rarely use blocks are as
anonymous callback functions, which was probably the source of your
pain in other languages.

Often Ruby blocks are just three or four lines of code that are
inlined into a still small function, so as long as the outer function
is still small (which Ruby's blocks help with--they promote
terseness), it's pretty easy to find a buggy function within a
traceback that is not overly big.

It's also possible in Ruby to use quality-promoting techniques like
unit testing, pair programming, deliberateness, etc., to avoid the
need for looking at tracebacks in the first place.

Python is not immune to hard-to-understand tracebacks, since you often
don't often know how a method got itself into the stracktrace in the
first place:

Traceback (most recent call last):
  File foo.py, line 11, in module
foo(method)
  File foo.py, line 2, in foo
method()
  File foo.py, line 5, in bar
raise Exception('I am broken!')
Exception: I am broken!

Even though there's no direct lexical reference to bar() in foo(), lo
and behold, foo() ends up calling bar():

def foo(method):
method()

def bar():
raise Exception('I am broken!')

def broken_function_factory():
return bar

method = broken_function_factory()
foo(method)
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-17 Thread Carl Banks
On Feb 17, 10:39 am, John Bokma j...@castleamber.com wrote:
 Jonathan Gardner jgard...@jonathangardner.net writes:
  Then I looked at a stack trace from a different programming language
  with lots of anonymous functions. (I believe it was perl.)

  I became enlightened.

 If it was Perl [1], I doubt it. Because line numbers are reported

Ok so sonetimes I'm looking at a stack trace and sometimes I can tell
what the bug is just by lookong at the function namess.  But if it has
just line numbers I have to dig through my code looking for the line.


 and
 if that doesn't help you, you can annotate anonymous functions with a
 nick name using

 local *__ANON__ = 'nice name';

 Finding an issue, and not looking for a solution is not called becoming
 enlightened ;-)

The issue is that a stacktrace showing a bunch of nameless line
numbers can be a bad idea, not that Perl might be deficient (and we
already know that in any case), so it's not good to use a lot of
them.  Anyway once you annotate an anonymous function, it's no longer
anonymous.


 ~$ perl -e '
 use Carp;

 my $anon = sub { local *__ANON__ = hello, world; croak oops; };
 $anon-();
 '

 oops at -e line 4
         main::hello, world() called at -e line 5

 As you can see, and a line number is generated, and the nice name is
 shown.

 If you generate anonymouse functions on the fly based on parameters, you
 can encode this into the nice name, of course.

 Sadly, often bold statements about a language are made in ignorance.

I don't see what he said was any kind of a bold statement about a
language, arguably it was about the coding style.  That Perl allows
annotating functions doesn't mean people do it.


Carl Banks

 [1] perl is the program that executes Perl programs ;-).

 --
 John Bokma                                                               j3b

 Hacking  Hiking in Mexico -  http://johnbokma.com/http://castleamber.com/- 
 Perl  Python Development

-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-16 Thread Casey Hawthorne
Interesting talk on Python vs. Ruby and how he would like Python to
have just a bit more syntactic flexibility.

http://blog.extracheese.org/2010/02/python-vs-ruby-a-battle-to-the-death.html
--
Regards,
Casey
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-16 Thread Andrej Mitrovic
On Feb 16, 7:38 pm, Casey Hawthorne caseyhhammer_t...@istar.ca
wrote:
 Interesting talk on Python vs. Ruby and how he would like Python to
 have just a bit more syntactic flexibility.

 http://blog.extracheese.org/2010/02/python-vs-ruby-a-battle-to-the-de...
 --
 Regards,
 Casey

Gary's friend Geoffrey Grosenbach says in his blog post (which Gary
linked to): Python has no comparable equivalent to Ruby’s do end
block. Python lambdas are limited to one line and can’t contain
statements (for, if, def, etc.). Which leaves me wondering, what’s the
point?

I'm sorry, lambda's do support if's and for's. Also, lambda's are
expressions, not statements, but you can pass them around, keep them
in a dictionary if you want to. And if you need more than one line of
statements, for crying out loud use a def? And who needs those do-
end blocks anyway, trying to turn Python into Pascal?
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-16 Thread Jonathan Gardner
On Feb 16, 11:41 am, Andrej Mitrovic andrej.mitrov...@gmail.com
wrote:
 On Feb 16, 7:38 pm, Casey Hawthorne caseyhhammer_t...@istar.ca
 wrote:

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

 http://blog.extracheese.org/2010/02/python-vs-ruby-a-battle-to-the-de...
  --
  Regards,
  Casey

 Gary's friend Geoffrey Grosenbach says in his blog post (which Gary
 linked to): Python has no comparable equivalent to Ruby’s do end
 block. Python lambdas are limited to one line and can’t contain
 statements (for, if, def, etc.). Which leaves me wondering, what’s the
 point?

 I'm sorry, lambda's do support if's and for's. Also, lambda's are
 expressions, not statements, but you can pass them around, keep them
 in a dictionary if you want to. And if you need more than one line of
 statements, for crying out loud use a def? And who needs those do-
 end blocks anyway, trying to turn Python into Pascal?

I used to think anonymous functions (AKA blocks, etc...) would be a
nice feature for Python.

Then I looked at a stack trace from a different programming language
with lots of anonymous functions. (I believe it was perl.)

I became enlightened.
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-16 Thread Aahz
In article 8ca440b2-6094-4b35-80c5-81d000517...@v20g2000prb.googlegroups.com,
Jonathan Gardner  jgard...@jonathangardner.net wrote:

I used to think anonymous functions (AKA blocks, etc...) would be a
nice feature for Python.

Then I looked at a stack trace from a different programming language
with lots of anonymous functions. (I believe it was perl.)

I became enlightened.

+1 QOTW
-- 
Aahz (a...@pythoncraft.com)   * http://www.pythoncraft.com/

At Resolver we've found it useful to short-circuit any doubt and just
refer to comments in code as 'lies'. :-)
-- 
http://mail.python.org/mailman/listinfo/python-list


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

2010-02-16 Thread David Cournapeau
On Wed, Feb 17, 2010 at 4:41 AM, Andrej Mitrovic
andrej.mitrov...@gmail.com wrote:

 Gary's friend Geoffrey Grosenbach says in his blog post (which Gary
 linked to): Python has no comparable equivalent to Ruby’s do end
 block. Python lambdas are limited to one line and can’t contain
 statements (for, if, def, etc.). Which leaves me wondering, what’s the
 point?

 I'm sorry, lambda's do support if's and for's. Also, lambda's are
 expressions, not statements, but you can pass them around, keep them
 in a dictionary if you want to. And if you need more than one line of
 statements, for crying out loud use a def?

I think that's a bit of a strawman: the point made by the OP is that
it enables writing simple DSL easier, and the ruby's community seems
to value this. They are not advocating using anonymous functions where
normal functions would do.

cheers,

David
-- 
http://mail.python.org/mailman/listinfo/python-list