Date: Fri, 2 Mar 2001 12:25:22 +0900
   Posted: Fri, 02 Mar 2001 12:25:21 +0900
   From: matz / zetabits.com (Yukihiro Matsumoto)
   Reply-To: ruby-talk / ruby-lang.org

   In message "[ruby-talk:11878] Re: Option to allow Python style indenting?"
       on 01/03/02, Eric Sven Ristad <ristad / mnemonic.com> writes:

   |A central beauty of Ruby is that most everything is EXPLICIT.

   I want Ruby to be as explicit as possible where it should be explicit,
   and as implicit (or in other word, smart) as possible where it doesn't
   make things confusing.

It's interesting that you chose to make variable scope and function
explicit but make their types and conversions implicit.  Personally, I
think this is the right choice for a scripting/prototyping language.
In my experience, you must adopt strict variable naming conventions
(that distinguish between locals/globals/constants, etc) if you want
your code to be readable.  Ruby takes the very clever step of actually
enforcing its variable naming conventions.  Very nice.

Type declarations and explicit conversions are necessary if you want
to write time- and space-efficient code that is also correct, but they
tend to be annoying in a scripting/protoyping language because (1)
most of the time you can determine the type from its name and use and
(2) you are willing to sacrifice some efficiency for the benefits of
quick prototyping.  So I think you made the right choice here too.

On a related note, I'm continually surprised at how nice the yield
statement is.  To implement iterators in C, I typically write an
enumerator that takes a procedure and applies it to all the elements
in the enumeration.  Something like:

	def vector_map(vector,proc,parameters)
	  for i in (0..array.length-1)
	     is_alive = proc(array[i],parameters)
	     if !is_alive then return end
          end
	end

This is annoying because the named proc cannot enjoy the scope in
which the iterator is called: you have to put its entire environment
in a struct and pass that in through the parameters argument.  The
alternative is to make the iterator itself preserve its state in a
struct, which tends to be substantially more messy when you are
iterating through a complex data structure.

In Ruby, you get the best of both worlds

	def array_map(array)
	  for i in (0..array.length-1)
  	      is_alive = yield array[i] 
	      if !is_alive then return end
          end
	end

because (1) the block you pass to the iterator enjoys the environment
in which the iterator is called, rather than the environment of the
iterator itself and (2) the iterator enjoys its own environment.  This
simple feature makes writing iterators at least 10 times easier than
in C and similar languages.

My only reservation about the Ruby yield statement is that I would
prefer if the arity of the block and yield statements were strictly
matched, to enhance correctness.  Something like: if the block takes
any arguments, then it must take the exact same number of arguments as
the yield statement provides or a runtime error occurs.

Eric