Why "yield return" rather than "yield"?
This came up in another context, and I thought I'd share the story.
In the first version of iterators, you would use "yield" when you wanted to "return" a iterator value back, and things worked great. So, that's that way it was for quite a long period.
We knew at the start of the 2.0 effort that we were doing some major things to the language, and major things often require new keywords. It seemed likely that some of the generics work would lead to this.
So, we planned on how to deal with it. Now, new keywords are bad. Bad, because developers have the annoying habit of using non-keywords as identifiers (someday I'll tell the story of the generated FORTRAN code I worked on when I was fresh out of college), and if their choice happens to align with a keyword, their used-to-be-working-perfectly code now breaks.
Which is, as they say, bad.
So, we came up with a mitigation strategy - we would provide a utility that you could run over your source code, and it would replace any identifier that had become a keyword with the escaped version. It does this by putting an "@" sign in front of it.
I expect to see heavy usage of "@" in any obfuscated C# contests...
So, anyway, we had this plan in place. But as we finished the work with generics, we found that we had managed to do it without any real keywords (see my next post for more information...).
This meant that the only new keyword in 2.0 was "yield", and switching to yield return meant that C# 2.0 would compile all C# code without change.
Which is good.
Comments
- Anonymous
March 08, 2006
The comment has been removed - Anonymous
March 08, 2006
yield is still a keyword, it's just context-sensitive so it's not a reserved word. I'm just glad it's not like some versions of ALGOL where you would have to quote every keyword:
'if' n 'notequal' 1 'then' 'goto' do; - Anonymous
March 08, 2006
@ is there primarly because .NET is a multi-language environment. It's possible to reference a class with a identifier that matches one of your keywords, and C# needs a way to be able to write that.
C# does not reserve identifiers that start with "_". I recall that we talked about it at one point but don't recall anything beyond that, and I couldn't find mention in the design notes.
My personal feeling is that putting underscores in front of a keyword is both an ugly and a confusing thing to do to people, which is compounded in the C++ case by the use of double underscores in the some cases. I understand that for a language like C++, using _ was an expedient choice - and perhaps the only real choice given the realities of lots of different vendors - but I don't think it's a good one.
I also think having _ as an out makes it too easy to add features, not that I'm suggesting that that happened in the C++ case...
So, that's what I think, and I don't think there has been any real cause to regret that decision so far.
Eric - Anonymous
March 08, 2006
The comment has been removed - Anonymous
March 08, 2006
They had to pair any new contextual keyword with an existing keyword, otherwise the same problem of breaking code would occur which is what the contextual keyword was created to solve. - Anonymous
March 09, 2006
My "yield value = x" example would have been a breaking change (get rid of the =, in the case of "using yield = System.In32;"); but, that doesn't mean they had to use an existing keyword (contextual or not). They just had to use a syntax that could not have possibly complied before that. For example, "yield iteration obj;" could never have compiled in VCS 2003 and therefore "iteration" could be added as a new contextual keyword without causing existing code to break--even if "iteration" was used as an identifier.
They had the forethought to add the concept of conceptual keywords to help avoid having collisions with adding real keywords, brilliant. - Anonymous
March 28, 2006
Is there a way yield return could be used to flatten a hierarchical memory structure? As I understand, all yield statements must figure in the same method and we can not call sub-methods or do recursive calls to achieve the iteration. Is there any work-around? Thanks. - Anonymous
March 28, 2006
Jeff, check out the MSDN Magazine article "Create Elegant Code With Anonymous Methods, Iterators, And Partial Classes" (http://msdn.microsoft.com/msdnmag/issues/06/00/C20/default.aspx) which shows an example of "flattening" a binary tree with recursive iterations