Sure... IEnumerable was inconvenient suggesting a separate class to service
the enumeration, IEnumerator, and multiple operations: Current, MoveNext,
Reset. (I'll warp the definition of "operation" for a second if you don't
mind).
However, it existed within intuitive language semantics, whereas the new
"yield" keyword, while highly convenient, is also one of the most gross
warping of language concepts to date...
public IEnumerator GetEnumerator() {
foreach(foobar o in _co) yield return o;
}
So, it essentially redefines the concepts of how functions are supposed to
behave, as well as how return values interact with return types. It also
introduces the new keyword with a very specialized purpose.
One way to explain "yield", is to say that it boxes your object into an
IEnumerator, saves the execution state of your function, and also restores
the execution state the next time your function is called, even before the
keyword is invoked during regular instruction flow, so it establishes the
loop's next startup state. Therefore, it redefines the laws of instruction
sequencing, and is sort of a quantum keyword that exists in multiple spots at
once during the existance of that function.
It would make sense to have IEnumerate be an allowed combination of
IEnumerable and IEnumerator, and to add a GetNext function that can return
the proper generic variable type. Then make "yield" its own return-style
keyword:
(** Proposed Syntax:
public class Woo : IEnumerate
{
...
public object GetNext() {
if(_collection= =null) return null;
foreach(object obj in _collection) {
yield obj;
}
}
...
}
**)
This would still allow the full existing enumeration capability, but would
introduce this new style in a cleaner and more intuitive way. 4 5651
Marshal,
The problem with condensing the two interfaces into one is that you end
up losing the fact that a type can say "I can have my contained items
iterated through, and this is the mechanism by which you do it". That's
different from your interface, which says "I can have my contained items
iterated through, and ^I^ will do it". The IEnumerable/IEnumerator
functions are better, IMO, because it will allow for better encapsulation of
code, at the least.
The other problem with your proposal is that you can't tell if there are
any more items in your iteration. Yeah, you could check against return
value of GetNext for null, but if you are enumerating value types, then you
can't do this, since they can't be null (unless you use Nullable types, but
that wasn't around in 1.0, and you would have to do this ugly case logic to
determine if it was a value type or not, and then if it was null).
Using your method would end up looking something like this:
// An object, to check for null.
object o = null;
// The type of the object.
T t;
// Loop. You have to check for null here since your implementation would
return
// null if there are no items in the enumeration. The assumption here
// is that at the end of the loop, you would return null.
while ((o = collection.GetN ext()) != null)
{
// Cast to the original object.
t = (T) o;
// Do some stuff.
}
This is a little more messy than what you have to do now. First, you
need to have the object instance just to check null, and you have a nasty
assignment and comparison in the while statement. Compare that to how
foreach is expanded by the compiler using the current IEnumeration interface
(and assuming that collection implements IEnumeration):
// The type t.
T t;
while (!collection.Mo veNext())
{
// Get the value.
t = collection.Curr ent;
}
You have t, and you know if you hit the end, but without that ugliness
in between (the o variable checking for null).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m
"Marshal" <Ma*****@discus sions.microsoft .com> wrote in message
news:17******** *************** ***********@mic rosoft.com... Sure... IEnumerable was inconvenient suggesting a separate class to service the enumeration, IEnumerator, and multiple operations: Current, MoveNext, Reset. (I'll warp the definition of "operation" for a second if you don't mind).
However, it existed within intuitive language semantics, whereas the new "yield" keyword, while highly convenient, is also one of the most gross warping of language concepts to date...
public IEnumerator GetEnumerator() { foreach(foobar o in _co) yield return o; }
So, it essentially redefines the concepts of how functions are supposed to behave, as well as how return values interact with return types. It also introduces the new keyword with a very specialized purpose.
One way to explain "yield", is to say that it boxes your object into an IEnumerator, saves the execution state of your function, and also restores the execution state the next time your function is called, even before the keyword is invoked during regular instruction flow, so it establishes the loop's next startup state. Therefore, it redefines the laws of instruction sequencing, and is sort of a quantum keyword that exists in multiple spots at once during the existance of that function.
It would make sense to have IEnumerate be an allowed combination of IEnumerable and IEnumerator, and to add a GetNext function that can return the proper generic variable type. Then make "yield" its own return-style keyword:
(** Proposed Syntax: public class Woo : IEnumerate { ... public object GetNext() { if(_collection= =null) return null; foreach(object obj in _collection) { yield obj; } } ... } **)
This would still allow the full existing enumeration capability, but would introduce this new style in a cleaner and more intuitive way.
> The problem with condensing the two interfaces into one is that you end up losing the fact that a type can say "I can have my contained items iterated through, and this is the mechanism by which you do it". That's different from your interface, which says "I can have my contained items iterated through, and ^I^ will do it". The IEnumerable/IEnumerator functions are better, IMO, because it will allow for better encapsulation of code, at the least.
My proposal should be equivilent with the current proposals on using
"yield", it just cleans up the syntax. In both cases, you can still use
IEnumerable and IEnumerator for the reasons you point out, and both proposals
on "yield" are used for the ^I^ will do it case anyway.
The other problem with your proposal is that you can't tell if there are any more items in your iteration...
Again, it's basically a cleaner way of expressing the existing yield syntax,
which has no problem terminating the enumeration in magic code. I was imaging
it being used in a foreach statement.
If the GetNext function is called directly as in your example, then I would
expect it should throw an exception if the caller tries to read beyond the
end of the array. They should write something like:
(** Proposed Syntax:
collection.Rese t();
while(collectio n.HasValues) { o = collection.GetN ext(); ... }
**)
However, they should be as unlikely to do that, as they would be to call
GetEnumerator directly in the current model which uses yield. If they did so
in the current model, it would not appear as intuitive.
Using your method would end up looking something like this:
// An object, to check for null. object o = null;
// The type of the object. T t;
// Loop. You have to check for null here since your implementation would return // null if there are no items in the enumeration. The assumption here // is that at the end of the loop, you would return null. while ((o = collection.GetN ext()) != null) { // Cast to the original object. t = (T) o;
// Do some stuff. }
This is a little more messy than what you have to do now. First, you need to have the object instance just to check null, and you have a nasty assignment and comparison in the while statement. Compare that to how foreach is expanded by the compiler using the current IEnumeration interface (and assuming that collection implements IEnumeration):
// The type t. T t;
while (!collection.Mo veNext()) { // Get the value. t = collection.Curr ent; }
You have t, and you know if you hit the end, but without that ugliness in between (the o variable checking for null).
-- - Nicholas Paldino [.NET/C# MVP] - mv*@spam.guard. caspershouse.co m
See inline: The other problem with your proposal is that you can't tell if there are any more items in your iteration... Again, it's basically a cleaner way of expressing the existing yield syntax, which has no problem terminating the enumeration in magic code. I was imaging it being used in a foreach statement.
Ok, so it's cleaner, but at what cost? Clean doesn't mean anything if
actually implementing it is not.
If the GetNext function is called directly as in your example, then I would expect it should throw an exception if the caller tries to read beyond the end of the array. They should write something like:
(** Proposed Syntax: collection.Rese t(); while(collectio n.HasValues) { o = collection.GetN ext(); ... } **)
There is a specific reason why the designers of .NET didn't use
something like HasValues and GetNext. The reason for that is that a good
number of people actually forget to code the call to move to the next item
in the enumeration, leading to infinite loops. With the way it is now (with
the all to MoveNext returning whether or not there are elements), you don't
have that problem.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m However, they should be as unlikely to do that, as they would be to call GetEnumerator directly in the current model which uses yield. If they did so in the current model, it would not appear as intuitive.
Using your method would end up looking something like this:
// An object, to check for null. object o = null;
// The type of the object. T t;
// Loop. You have to check for null here since your implementation would return // null if there are no items in the enumeration. The assumption here // is that at the end of the loop, you would return null. while ((o = collection.GetN ext()) != null) { // Cast to the original object. t = (T) o;
// Do some stuff. }
This is a little more messy than what you have to do now. First, you need to have the object instance just to check null, and you have a nasty assignment and comparison in the while statement. Compare that to how foreach is expanded by the compiler using the current IEnumeration interface (and assuming that collection implements IEnumeration):
// The type t. T t;
while (!collection.Mo veNext()) { // Get the value. t = collection.Curr ent; }
You have t, and you know if you hit the end, but without that ugliness in between (the o variable checking for null).
-- - Nicholas Paldino [.NET/C# MVP] - mv*@spam.guard. caspershouse.co m
Marshal wrote: Sure... IEnumerable was inconvenient suggesting a separate class to service the enumeration, IEnumerator, and multiple operations: Current, MoveNext, Reset. (I'll warp the definition of "operation" for a second if you don't mind).
IEnumerable expresses that enumeration is supported, "I am iterable, you
can obtain that enumeration by invoking GetEnumerator() ".
IEnumerator expresses a "pointer" into an enumeration, "This is how far
you are along the enumeration".
IEnumerator have Current/MoveNext(), JAVA Iterator have hasNext() and
next(), C++ iterators have "++" and "*". Actually I don't recall seeing
any protocol for iteration that don't have seperate
advance/advance-check and value obtain, and thus multiple operations.
I would say that whether Reset() should be included in IEnumerator is
open to discussion.
So, it essentially redefines the concepts of how functions are supposed to behave, as well as how return values interact with return types. It also introduces the new keyword with a very specialized purpose.
It lets you define a generator for IEnumerator using function-syntax.
Other languages have this too, python and it is essential in ruby.
Whether this "redefines the concepts of how functions work" or not...
well, you are really just defining a function that returns an
enumerator. There is no "quantum magic" here, only compiler assisted
closure greneration.
Notice that the caller of the function doesn't care if actual "quantum
magic" was used to implement the IEnumerator returned. The implementer u
could do it by implementing the closure, MoveNext() and Current by hand
in a class that stores the relevant state and implement IEnumerator.
Function-syntax is rather nice for describing enumeration, and
syntactic-sugar support for storing the used local-variables in a
helper-class and implementing Current/MoveNext() is convinient to me in
that syntax.
One way to explain "yield", is to say that it boxes your object into an IEnumerator, saves the execution state of your function, and also restores the execution state the next time your function is called, even before the keyword is invoked during regular instruction flow, so it establishes the loop's next startup state. Therefore, it redefines the laws of instruction sequencing, and is sort of a quantum keyword that exists in multiple spots at once during the existance of that function.
Another way to explain it would be that it generates an IEnumerators
MoveNext() and Current functions from the closure available in the
function. This is a known technique known from functional programming: a
higher-order function.
It would make sense to have IEnumerate be an allowed combination of IEnumerable and IEnumerator, and to add a GetNext function that can return the proper generic variable type. Then make "yield" its own return-style keyword:
I don't see the benefit of combining IEnumerable and IEnumerator, see above.
The problems in combining the two concepts is manifest in our
example-code. Where is _collection coming from (the interface-usage
prevents you from having a protocol of accepting it at construction time).
(** Proposed Syntax: public class Woo : IEnumerate { ... public object GetNext() { if(_collection= =null) return null; foreach(object obj in _collection) { yield obj; } } ... } **)
I don't really understand how this is substantially different from or
better than:
public static IEnumerator Enumerate(IColl ection c) {
foreach ( object o in c )
yield return o;
}
Which fits into the current enumeration-idiom in C#.
The choice of "yield return" vs. just "yield" is open to discussion, but
i suspect "yield return" was chosen because no program containing that
sequence of tokens would be valid in previous C# revisions.
This would still allow the full existing enumeration capability, but would introduce this new style in a cleaner and more intuitive way.
Perhaps you are finding the IEnumerable/IEnumerator design
non-intuitive, and perhaps transfer that onto the "yield return" construct?
I find that the IEnumerable/IEnumerator design is spot-on and I haven't
really seen any languages which doesn't make that distinction in one
form or another.
Perhaps you need just a little more assimilation before you accept the
design ;) (notice smiley.... i'm not being hostile here)
--
Helge Jensen
mailto:he****** ****@slog.dk
sip:he********* *@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=- This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Andrew James |
last post by:
Gentlemen,
I'm currently in the process of designing a language which will be used
to specify sets of files on a WebDAV server, encoded in a URL. The aims
of the language are to (in no particular order):
* Be concise, aesthetic and easy to type
* Be as similar as possible to existing query languages
* Allow for (nested) boolean operations
*...
|
by: Justin Wright |
last post by:
I know that I can set up an enumeration as follows ( just typed in quick so
may have syntax errors ):
<xsd:simpleType name="colors">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="red"/>
<xsd:enumeration value="yellow"/>
<xsd:enumeration value="blue"/>
</xsd:simpleType>
|
by: Tristan Miller |
last post by:
Greetings.
Do any popular browsers correctly support <q>, at least for Western
languages? I've noticed that Mozilla uses the standard English
double-quote character, ", regardless of the lang attribute of the HTML
document. Will any browsers render German-style quotes or French-style
guillemots for lang="de" and lang="fr", respectively?
...
|
by: Randy Yates |
last post by:
In Harbison and Steele's text (fourth edition, p.111)
it is stated,
The C language does not specify the range of integers that the
integral types will represent, except ot say that type int may not
be smaller than short and long may not be smaller than int.
They go on to say,
Many implementations represent characters in 8 bits, type...
|
by: Tony Whitter |
last post by:
Does anyone know how much changed between the final draft dated October 2002
and the Ecma-334 C# Language Specification 2nd edition dated December 2002
and if there is a change history document anywhere?
Thanks in anticipation.
Tony
| |
by: Eric Gunnerson [MS] |
last post by:
You may download the new specification at the C# Developer Center
(http://msdn.microsoft.com/vcsharp/language). There is a discussion forum
for the C# language on that same page.
If you don't own a copy of MS Word, you can download the free viewer at:
...
|
by: Marshal [DirectX MVP 2003] |
last post by:
In anticipation of the chat, I have filtered all of my current enhancement
aleration ideas through the software development community, via the following
postings:
C# Language Specification - Delegates
C# Language Specification - Extension Methods
C# Language Specification - Enumeration
C# Language Specification - Generics
If anybody...
|
by: albert.neu |
last post by:
Hello!
What is the difference between "library parts" of C99 and "language
parts" of C99.
see
http://groups.google.at/group/microsoft.public.vc.language/browse_thread/thread/e9a67f0ff20a954b/bd2bada2bbdbce56?lnk=st&rnum=1#bd2bada2bbdbce56
I know that "Dinkum Compleat Libraries" (http://www.dinkumware.com/)
support the "library parts"...
|
by: Vneha |
last post by:
Q:- What is the difference between Sun Java tutorials and Java Language specification?
Q:- What if i start studying Java Language Specification and leave the tutorials because i have seen that Java Language Specification is much more in detail and covers all the topic that are in Java tutorials.?
Regards,
Neha
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
| |
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |