On Tue, 24 Feb 2004 15:41:01 -0700, "Ara.T.Howard"
<ahoward / fattire.ngdc.noaa.gov> wrote:
>On Tue, 24 Feb 2004, David MacQuigg wrote:
>
>> I'm not seeing any fundamental advantage of Ruby blocks over Python
>> functions.  
>
>there are no fundamental advantages of _any_ turing complete language over
>another correct?  iff so this is kindof a moot statement. 

What I mean by "fundamental advantage" is not anything to do with
Turing completeness, but rather the amount of effort required to
perform useful tasks, assuming equal familiarity with the chosen
language.  This has to be something more than just personal
preference.  It seems to me there is no fundamental advantage of
(-1942).abs over abs(-1942), although I prefer the latter.

I'm finding it very difficult to separate fundamental advantage from
personal preference, but I think we can all agree that
fnlt = line.chomp.squeeze.split(/\s*\|\s*/)
is less mental effort than
fnlt = [' '.join(t.split()).strip() for t in line.split('|')]

It seems to me there is something more fundamental here than personal
preference.  With the first statement, I can type the operations in
the order that I need to visualize intermediate results.  I can even
hit return with each added method, and see these intermediate results
on the screen.  Then 'up arrow' and continue with the next step.  With
the second statement, I really have to struggle, building it
piece-by-piece, with lots of cut-and-paste.  This extra effort is in
spite of the fact that, being a Python user, I am more familiar with
the methods in the second statement.

This string processing problem is one of the few examples I have been
able to isolate where Ruby has what I would call a fundamental
advantage over Python.  Everything else so far has turned out to be
less-than-optimimum coding, or just personal preference.

> however there is a
>'difference': blocks form closures, function calls do not:
>
>  def callback; yield; end
>  def a_callback? x; x = 42; end
>
>  x = nil
>  callback{ x = 42 }
>  p x                   # => 42
>
>  x = nil
>  a_callback? x
>  p x                   # => nil
>

I don't understanding the purpose of this example, so I don't know how
to write some Python that we can compare it with.  We need to back up
a step or two and say what useful result we are trying to achieve.
With that as a starting point, maybe we can resolve a question like
"Are closures really necessary?"

>> If your block is more than one line, or needs a print statement, just give
>> it a name and let it be a function.  lambda's are used only for very short
>> blocks, where for example, you want to pass a simple function in an argument
>> list, but don't want to waste a line giving that function a name.
>
>technically speaking (see above) this is true.  however, consider apis which
>have a massive proliferation of callbacks passed using blocks - say a gui api.
>writing a separate method for each button may be over kill and not lend itself
>to abstraction very well.  there were a series of articles onlines recently
>where matz said something about concentrating on the human aspect of computing
>and that really rang true to me, what i mean is:

Python and Ruby share a common goal here - making programming easier
for humans.  I've been pretty happy with Python since I started using
it about a year ago.  Just recently, some folks I'm working with in
the UserLinux group told me that Ruby was something we should
consider, so I started investigating.  Most of what I've found highly
touted in Ruby turns out to be just personal preference, but having
found the example above, I believe there may be a few more.

I think what has happened is that both languages have adopted each
others best features, so there may be no longer many fundamental
differences that can be shown with short examples.  It may be that the
remaining examples are larger than just the five-line snippets I was
hoping to put on our web page.

I have to break from this project and get some other work done, but I
will study the example below and others that have been suggested.  

--Dave

>would you rather see
>
>  comment = %r/^\s*#/o 
>  empty = %r/^\s*$/o
>
>  open(path).each do |line|
>    next if line =~ emtpy or line =~ comment 
>    key, value = line.split(%r/=/o).map{|x| x.strip}
>    opts[key] = value
>  end
>
>or
>
>  f = open(path)
>  comment = %r/^\s*#/o 
>  empty = %r/^\s*$/o
>
>  begin
>    while((line = f.gets))
>      next if line =~ emtpy or line =~ comment 
>      parse_line line, opts
>    end
>  ensure
>    f.close
>  end
>
># insert 1000 lines of source code here so pare_line is nice and tough to find
>
>  def parse_line line, opts
>    key, value = line.split(%r/=/o).map{|x| x.strip}
>    opts[key] = value
>  end
>
>
>doesn't matter?  how about if there a 50 of them?  100?  if there were a
>hundred of them would you rather see
>
>  handlers = Hash[
>    :foobar => proc{|arg| p arg},
>    :barfoo => proc{|arg| raise arg},
>    :foo    => proc{|arg| throw arg},
>    # 100 more...
>  ]
>
>
>or
>
>  # these are handlers - have fun naming all of them
>  def foobar arg; p arg; end
>  def barfoo arg; raise arg; end
>  def foo arg;    throw arg; end
>  # 100 more...
>
>now say you actually had to pass 20 or so handlers to a method - how would you
>do this with functions?  it would surely be uglier than:
>
>  parse_config handlers
>
>obviously you could maintain a string list of all the handlers and keep it in
>sync with your definitions.... (sounds like a job for code generation -
>tedious!)
>
>see what i'm driving at: skipping around the source finding all those defs can
>be frustrating and lead to errors.  the stack overhead is also higher - though
>that probably _really_ is moot!  ;-) 
>
>> I like Ruby's more compact |x| instead of Python's keyword - lambda x: - but
>> that is just my personal preference.
>
>that's as 'fundamental' as it gets with turing languages - look no further! ;-)
>
>truely - much research has been done to correlate a programmer's productivity
>with lines of code written - NOT with the type of code, in otherwords:
>
>  'compact' => 'advantage'
>
>and, i beleive, this relationship is some sort of exponential curve.
>
>cheers.
>
>-a