Ken Bloom wrote: > On Sun, 10 Sep 2006 15:05:10 -0700, Paul Lutus 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". :) -- Paul Lutus http://www.arachnoid.com