Ken Bloom wrote:
Newbie wrote:
So, from a language design perspective, what would be wrong with this?
do
stuff
do
risky stuff
rescue
SOS
end
more stuff
end while bored
"do" doesn't work this way -- it's an iterator (loosely speaking).
"begin" is not an iterator. They are different. There are good reasons to
make this distinction.
What *are* those reasons? That's the whole point of his question.
"do" reads from a list of items and provides them to its controlling block:
(implicit "do")
array.each { |item|
# do something here
}
(explicit "do")
array.each do |item|
# do something here
end
These two forms are interchangeable. One can argue that "do" is an implicit
"{ ... }" block, or the reverse. But the point is "do" receives items and
operates on them one at a time, then exits when its stream is empty.
"begin" doesn't get fed with items, it has a different purpose. It
demarcates a controlled block, to which a "rescue" clause might apply, or
to which a "while" test might apply, or others. And a "begin" block won't
persist on its own. Without some internal block that does something
repetitive (or a "while" test at the end), the "begin" block will exit in
one pass.
There is a need for both "do" and "begin" blocks. There is a need to
distinguish syntactically between a block that must be fed with items, and
one that must not be fed with items. To combine "do" and "begin" would lead
to syntactical ambiguity ... and surely then someone would ask why the two
purposes of "do" were not more clearly distinguished in the syntax.
If "do" and "begin" were to be merged, it would be a little like the
ambiguous use of "<<" in C++. In one context, it shifts bits:
int x = 1,y;
y = x << 4; // y = 16
In another context, "<<" inserts items into a stream:
iostream x;
bool y;
y = x << 4; // y = true if the operation was successful
See the problem? Without my clear declarations directly above each case, you
would have a hard time distinguishing cases that use the same syntax. This
would make program listings hard to interpret and debug (a fact in C++).
The multiple uses of "<<" in C++ is a well-known example, but the point I am
making is that it's important to avoid ambiguous syntax in language design.
"do ... end" always has a stream, and when the stream is exhausted, the
block exits. "begin ... end" never has a stream. It's easy to remember and
easy to read.
The end result of responding to every request for creative syntax variations
is called ... umm ... "Perl". 
···
On Sun, 10 Sep 2006 15:05:10 -0700, Paul Lutus wrote:
--
Paul Lutus
http://www.arachnoid.com