I don't believe a syntax driven equivalent exists for this, but I just
thought it would be neat if you could use foreach to do something like this:
foreach (Object x in collection1, collection2)
and have it sequentially enumerate through both of them. 14 1680
"Josh Ferguson" <_j***********@semo.edu> wrote in
news:eV**************@TK2MSFTNGP12.phx.gbl... I don't believe a syntax driven equivalent exists for this, but I just thought it would be neat if you could use foreach to do something like this:
foreach (Object x in collection1, collection2)
and have it sequentially enumerate through both of them.
I think you can do something that comes quite close:
foreach (Object x in new Combine(collection1, collection2))
Where "Combine" is a class that stores the lists it gets in the ctor and
implements IEnumerable to enumerate over them.
Anyway, I think it would be nice to have real syntax support for this, as it
could remove unneccesary casting/boxing.
Niki
what happens if both of the collections are of different lengths though. and
where would you put the object from collection2 you can't put it into x
because that is where the item from collection1 is going and why stop at two
collection why not allow any number of collections. It might look like a
nice idea but it starts to get horribly complicated, however many
collections you allow in foreach some one is going to want 1 more
collection.
You could use a while loop and the collection iterators. Although there is
still the problem of what to do if the collections are of differnt lengths.
I'm not sure I can think of any reason why you would want to do this anyway.
Most of the things I can think of would be set type operations and you would
only want to iterate through one of the collection at a time anyway.
Paul.
"Josh Ferguson" <_j***********@semo.edu> wrote in message
news:eV**************@TK2MSFTNGP12.phx.gbl... I don't believe a syntax driven equivalent exists for this, but I just thought it would be neat if you could use foreach to do something like
this: foreach (Object x in collection1, collection2)
and have it sequentially enumerate through both of them.
"Josh Ferguson" <_j***********@semo.edu> wrote: foreach (Object x in collection1, collection2) and have it sequentially enumerate through both of them.
Sounds like a job for a nested loop, unless for some reason you really
need to do it very often.
foreach (Collection c in new Collection[] { collection1,
collection2 })
{
foreach (Object x in c)
{
P.
"Niki Estner" <ni*********@cube.net> wrote in message
news:e7*************@TK2MSFTNGP11.phx.gbl... "Josh Ferguson" <_j***********@semo.edu> wrote in news:eV**************@TK2MSFTNGP12.phx.gbl...I don't believe a syntax driven equivalent exists for this, but I just thought it would be neat if you could use foreach to do something like this:
foreach (Object x in collection1, collection2)
and have it sequentially enumerate through both of them. I think you can do something that comes quite close:
foreach (Object x in new Combine(collection1, collection2))
Where "Combine" is a class that stores the lists it gets in the ctor and implements IEnumerable to enumerate over them.
Anyway, I think it would be nice to have real syntax support for this, as it could remove unneccesary casting/boxing.
There really wouldn't be anymore or any less casting with this syntax than
norma.. Generics are quite suitable:
Combine<T>(params ICollection<T>[] collections); Niki
"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
Newsbeitrag news:O$**************@TK2MSFTNGP10.phx.gbl... ... There really wouldn't be anymore or any less casting with this syntax than norma.. Generics are quite suitable:
Combine<T>(params ICollection<T>[] collections);
Really?
I haven't looked at .net generics enough; Could I actually do something
like:
int[] intArray;
long[] longArray;
....
foreach (long x in new Combine(intArray, longArray))
...
with such a template?
Niki
"Niki Estner" <ni*********@cube.net> wrote in message
news:eh**************@tk2msftngp13.phx.gbl... "Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in Newsbeitrag news:O$**************@TK2MSFTNGP10.phx.gbl... ... There really wouldn't be anymore or any less casting with this syntax than norma.. Generics are quite suitable:
Combine<T>(params ICollection<T>[] collections);
Really? I haven't looked at .net generics enough; Could I actually do something like:
int[] intArray; long[] longArray; ... foreach (long x in new Combine(intArray, longArray))
No, you would have to cast in that situation because
longArray and intArray implement ICollection<long> and ICollection<int>
respectivly. So you would have to do some conversion in this
situation(although it will work perfectly well
in homogenous situations).
Unfortunatly, the same thing would happen with direct langauge support.
foreach requires a conversion to long because the IEnumerator implementation
can only return one type. So, you would have a conversion of each value
individually instead of a broad conversion across the whole array, I can't
honestly say which is better, can you? (the above combine could be modified
to allow a looser limitation on types and do the same thing as a built in
feature would:
T Combine<T,V>(ICollection<T> part1, ICollection<V> part2);
but it isn't the prettiest thing).
Some support concepts, like list comprehensions and range generators *might*
be capable of a much better job, but that isn't directly related to foreach
itself.
"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
Newsbeitrag news:OC***************@TK2MSFTNGP11.phx.gbl... ... Unfortunatly, the same thing would happen with direct langauge support. foreach requires a conversion to long because the IEnumerator implementation can only return one type. So, you would have a conversion of each value individually instead of a broad conversion across the whole array, I can't honestly say which is better, can you?
I'd think:
foreach (x in a, b) {...}
would be a shorthand for:
foreach (x in a) {...}
foreach (x in b) {...}
Of course this has to *convert* values if 'x' is not of the same type as one
of the array's base types; But it doesn't have to box/unbox anything. A
solution that has to cast to IEnumerable has to.
(the above combine could be modified to allow a looser limitation on types and do the same thing as a built in feature would:
T Combine<T,V>(ICollection<T> part1, ICollection<V> part2);
can you specify in a 'where' clause that 'V' must be convertible to 'T'
(again, without boxing)? I thought that wasn't possible. But, as I said, I
haven't had the time yet to take a deeper look into 2.0 features...
Niki
"Niki Estner" <ni*********@cube.net> wrote in message
news:O9**************@TK2MSFTNGP15.phx.gbl... "Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in Newsbeitrag news:OC***************@TK2MSFTNGP11.phx.gbl... ... Unfortunatly, the same thing would happen with direct langauge support. foreach requires a conversion to long because the IEnumerator implementation can only return one type. So, you would have a conversion of each value individually instead of a broad conversion across the whole array, I can't honestly say which is better, can you? I'd think: foreach (x in a, b) {...} would be a shorthand for: foreach (x in a) {...} foreach (x in b) {...}
Of course this has to *convert* values if 'x' is not of the same type as one of the array's base types; But it doesn't have to box/unbox anything. A solution that has to cast to IEnumerable has to.
Boxing only occurs when you pass something to *object*, not when you
convert. I don't see where boxing comes into this. If your collection
supports IEnumerable<T>, then there is no boxing involved, its just a
straight cast.
IEnumerator itself, yes, you have to deal with boxing if the contained
enumerator *is* boxed. However, with IEnumerable<T> its not an issue.
However, since foreach works on a pattern that IEnumerable and IEnumerator
happen to follow, it doesn't actually require those interfaces be
implemented, it is possible to optimize boxing away in some cases, except
IEnumerable<T> will become available *before* a compiler could be written to
support this functionality, making it far less attractive as IEnumerable<T>
is *much* nicer than just writing to the enumerable\enumerator pattern with
strongly typed return values and it eliminates boxing at its cause.
It would be some work, but this is entirely achievable without compiler
additions. The conversion routine can be aggervating, but it isn't terribly
hard.
can you specify in a 'where' clause that 'V' must be convertible to 'T' (again, without boxing)? I thought that wasn't possible. But, as I said, I haven't had the time yet to take a deeper look into 2.0 features...
No, you would have to use overloading:
public class Combine<T>
{
public Combine(ICollection<T> a, ICollection<T> b)
{
}
public Combine<V>(ICollection<T> a, ICollection<V> b) where T : struct,
V : struct
{
}
}
or what hve you, using the Convert class and\or judicious casting.
You can also use static methods to get clearer and more extensive semantics.
Anyway, I'm not arguing that a compiler extension wouldn't be easier, just
that its unneeded and wouldn't have any significant functionality benifit(it
may eliminate boxing in the rare edge case, but does that qualify for an
extesion when generics were already designed to do so?)
"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
Newsbeitrag news:ui**************@TK2MSFTNGP10.phx.gbl... "Niki Estner" <ni*********@cube.net> wrote in message news:O9**************@TK2MSFTNGP15.phx.gbl... "Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in Newsbeitrag news:OC***************@TK2MSFTNGP11.phx.gbl... ... Unfortunatly, the same thing would happen with direct langauge support. foreach requires a conversion to long because the IEnumerator implementation can only return one type. So, you would have a conversion of each value individually instead of a broad conversion across the whole array, I can't honestly say which is better, can you? I'd think: foreach (x in a, b) {...} would be a shorthand for: foreach (x in a) {...} foreach (x in b) {...}
Of course this has to *convert* values if 'x' is not of the same type as one of the array's base types; But it doesn't have to box/unbox anything. A solution that has to cast to IEnumerable has to.
Boxing only occurs when you pass something to *object*, not when you convert. I don't see where boxing comes into this. If your collection supports IEnumerable<T>, then there is no boxing involved, its just a straight cast.
IEnumerator itself, yes, you have to deal with boxing if the contained enumerator *is* boxed. However, with IEnumerable<T> its not an issue. However, since foreach works on a pattern that IEnumerable and IEnumerator happen to follow, it doesn't actually require those interfaces be implemented, it is possible to optimize boxing away in some cases, except IEnumerable<T> will become available *before* a compiler could be written to support this functionality, making it far less attractive as IEnumerable<T> is *much* nicer than just writing to the enumerable\enumerator pattern with strongly typed return values and it eliminates boxing at its cause.
It would be some work, but this is entirely achievable without compiler additions. The conversion routine can be aggervating, but it isn't terribly hard.
can you specify in a 'where' clause that 'V' must be convertible to 'T' (again, without boxing)? I thought that wasn't possible. But, as I said, I haven't had the time yet to take a deeper look into 2.0 features...
No, you would have to use overloading:
public class Combine<T> { public Combine(ICollection<T> a, ICollection<T> b) {
}
public Combine<V>(ICollection<T> a, ICollection<V> b) where T : struct, V : struct {
}
}
or what hve you, using the Convert class
AFAIK the Convert class takes an object parameter, so it requires boxing,
that's what I've been saying all the time.
and\or judicious casting.
I don't think you can simply cast 'V' to 'T' in a generic class as above;
Anyway, I'm not arguing that a compiler extension wouldn't be easier, just that its unneeded and wouldn't have any significant functionality benifit(it may eliminate boxing in the rare edge case, but does that qualify for an extesion when generics were already designed to do so?)
When I first looked at the idea I thought it would fit nicely into the
language without breaking any existing concepts. Also, it does have a some
benefits not acchievable with generics. So, although I don't think this is a
terribly important new feature, I wouldn't mind if it made it into the
language.
Niki
> and\or judicious casting. I don't think you can simply cast 'V' to 'T' in a generic class as above;
No, you can't. And actually I made a mistake.
Some time ago I wrote code that literally did just this, however, what I
forgot was that it was working with *strings* and not input values, so I was
doing parsing, not conversion.
Boxing probably will happen, come to think of it, although you wouldn't use
the object parameter of Convert, its more likely to happen when casting to
IConvertible.
This functionality would work perfectly well for two like lists, or two
lists with like bases(pretty much everything *except* structures, which I
would still call an edge case(though not as rare as I had originally
though)). Anyway, I'm not arguing that a compiler extension wouldn't be easier, just that its unneeded and wouldn't have any significant functionality benifit(it may eliminate boxing in the rare edge case, but does that qualify for an extesion when generics were already designed to do so?)
When I first looked at the idea I thought it would fit nicely into the language without breaking any existing concepts. Also, it does have a some benefits not acchievable with generics. So, although I don't think this is a terribly important new feature, I wouldn't mind if it made it into the language.
It would fit, but its just...not important enough to bother with. As I've
mentioned before, full list support would be a more admirable goal.
Also, there are alot of unanswered questions. Does the new collection take
the *type* T in
foreach (T t in a,b,c)
or does it take on the type of a's members? Some singular conversion would
have to happen eventually, so, except in the case of an array or specialized
enumerators(rare things, it seems), boxing is going to occur quite alot here
as well. That takes us back to my "no better, no worse" theory.
IEnumerator<T> makes it a bit better, but perhaps not too much.
Though, on a side note, I argued at one point that a given object *should*
be allowed to support multiple IEnumerator<T> implementations and a foreach
loop should choose the enumerator it wants based entirely on the type
declared in foreach. Using that standard would allow, say, an Int32
collection to expose a enumerator as Int64 as well.
The problem, of course, is it doesn't really help with regards to generic
collections, snce they are generic, you won't see many Int32Collection<T>'s,
;).
"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
news:ez**************@TK2MSFTNGP11.phx.gbl... ... When I first looked at the idea I thought it would fit nicely into the language without breaking any existing concepts. Also, it does have a some benefits not acchievable with generics. So, although I don't think this is a terribly important new feature, I wouldn't mind if it made it into the language. It would fit, but its just...not important enough to bother with.
I'd say it's a "cosmetic change". It's not really important, but (I think)
everone would instantly understand what it's good for, so I'd say it would
be a step in the right direction.
As I've mentioned before, full list support would be a more admirable goal.
I'm not really sure what that means...
Also, there are alot of unanswered questions. Does the new collection take the *type* T in foreach (T t in a,b,c)
or does it take on the type of a's members?
I'd expect it to work exactly the same way "foreach (T t in a)" does. AFAIK
this only needs boxing if
- T is object, and 'a' has a value-basetype, or
- 'a' only implements a 'plain' IEnumerable interface
Niki
"Niki Estner" <ni*********@cube.net> wrote in message
news:OS**************@TK2MSFTNGP12.phx.gbl... "Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in news:ez**************@TK2MSFTNGP11.phx.gbl... ... When I first looked at the idea I thought it would fit nicely into the language without breaking any existing concepts. Also, it does have a some benefits not acchievable with generics. So, although I don't think this is a terribly important new feature, I wouldn't mind if it made it into the language. It would fit, but its just...not important enough to bother with.
I'd say it's a "cosmetic change". It's not really important, but (I think) everone would instantly understand what it's good for, so I'd say it would be a step in the right direction.
A stept, yes, but too small to warrent on its own, IMHO. As I've mentioned before, full list support would be a more admirable goal.
I'm not really sure what that means...
Lists\list comprehensions are a feature of quite a few languages, mostly
functinoal it seems. They are a sort of inline list syntax combined with
single line iterators.
You could write soemthing like
foreach (int x in 1..10)
{
}
foreach(int x in [1,2,4,5,6])
{
}
or
foreach (int x in [yield a for int a = 1...1000 where a%2 == 0])
{
}
or
foreach (Customer customer in [yield a for Customer a = GetCustomers() where
a.Owed > 0]
(simple examples, madeup syntax). They generate lists and\or enumerators for
foreach to consume. There was a considerable thread about this...oh, some
time ago. Let me find it. http://groups.google.com/groups?hl=e...gbl%26rnum%3D2
Its huge, so I do not expect you to read it, however it holds a large part
of the discussion we held on these ideas.
One thing that had come up, but certainly hadn't been resolved was creating
a list out of two lists contents instead of a list of two lists. However,
something to achieve that would solve *this* problem cleanly within the
context of a number of other, more general purpose enhancements that
maintain the same basic syntactic conventions. I've been thinking about this
idea in more detail and certainly am not set with that syntax. However, at
some point I *do* intend to get a compiler working with this, life just
hasn't been giving me too many large blocks of free time lately, ;) Also, there are alot of unanswered questions. Does the new collection take the *type* T in foreach (T t in a,b,c)
or does it take on the type of a's members?
I'd expect it to work exactly the same way "foreach (T t in a)" does. AFAIK this only needs boxing if - T is object, and 'a' has a value-basetype, or - 'a' only implements a 'plain' IEnumerable interface
Hrmm, I think that would work. It just seems oddly defined, ;). For whatever
reason, it just seems to me that a,b,c should have a resolvable type, and
rules to define that.
"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
news:ON**************@TK2MSFTNGP15.phx.gbl... "Niki Estner" <ni*********@cube.net> wrote in message news:OS**************@TK2MSFTNGP12.phx.gbl... "Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in news:ez**************@TK2MSFTNGP11.phx.gbl... ... When I first looked at the idea I thought it would fit nicely into the language without breaking any existing concepts. Also, it does have a some benefits not acchievable with generics. So, although I don't think this is a terribly important new feature, I wouldn't mind if it made it into the language.
It would fit, but its just...not important enough to bother with. I'd say it's a "cosmetic change". It's not really important, but (I think) everone would instantly understand what it's good for, so I'd say it would be a step in the right direction.
A stept, yes, but too small to warrent on its own, IMHO.
It's a small, pragmatic change, like property accessor visiblility or static
classes. As long as they don't break the language's concept and help writing
readable code there's nothing wrong with these. As I've mentioned before, full list support would be a more admirable goal.
I'm not really sure what that means...
Lists\list comprehensions are a feature of quite a few languages, mostly functinoal it seems. They are a sort of inline list syntax combined with single line iterators.
You could write soemthing like
foreach (int x in 1..10) { }
foreach(int x in [1,2,4,5,6]) { }
or
foreach (int x in [yield a for int a = 1...1000 where a%2 == 0]) { }
or
foreach (Customer customer in [yield a for Customer a = GetCustomers() where a.Owed > 0]
Ahh, sounds like Haskell...
AFAIK Perl has a similar syntax; (simple examples, madeup syntax). They generate lists and\or enumerators for foreach to consume. There was a considerable thread about this...oh, some time ago. Let me find it.
http://groups.google.com/groups?hl=e...gbl%26rnum%3D2
Its huge, so I do not expect you to read it, however it holds a large part of the discussion we held on these ideas.
You're right, it *is* huge;
It seems people have been discussing pretty much anything in this thread...
One thing that had come up, but certainly hadn't been resolved was creating a list out of two lists contents instead of a list of two lists. However, something to achieve that would solve *this* problem cleanly within the context of a number of other, more general purpose enhancements that maintain the same basic syntactic conventions.
I see. Haskell has a special operator for that, "++" IIRC. But Haskell is
all about lists, C# isn't, so I'd say a utility function/class like the
"Combine" class above would probably be fine for that (if there was a way to
prevent uneccessary boxing); But I expect generics to be modified in that
respect in future versions of the framework anyway.
I've been thinking about this idea in more detail and certainly am not set with that syntax. However, at some point I *do* intend to get a compiler working with this, life just hasn't been giving me too many large blocks of free time lately, ;)
I definitely know what you mean...
Maybe you should sum up what you have already on a web page. I'd read it.
That is, if life will give me a large enough block of time :-)
Niki
"Niki Estner" <ni*********@cube.net> wrote in message
news:%2****************@tk2msftngp13.phx.gbl... "Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in news:ON**************@TK2MSFTNGP15.phx.gbl... "Niki Estner" <ni*********@cube.net> wrote in message news:OS**************@TK2MSFTNGP12.phx.gbl... "Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in news:ez**************@TK2MSFTNGP11.phx.gbl... ... > When I first looked at the idea I thought it would fit nicely into the > language without breaking any existing concepts. Also, it does have a > some benefits not acchievable with generics. So, although I don't > think this is a terribly important new feature, I wouldn't mind if it > made it into the language.
It would fit, but its just...not important enough to bother with.
I'd say it's a "cosmetic change". It's not really important, but (I think) everone would instantly understand what it's good for, so I'd say it would be a step in the right direction.
A stept, yes, but too small to warrent on its own, IMHO.
It's a small, pragmatic change, like property accessor visiblility or static classes. As long as they don't break the language's concept and help writing readable code there's nothing wrong with these.
Its not nessecerily so small. The grammer is something like
foreach (<type> <variable> in <embedded-expression>)
{
}
However, to add that feature would require either changing the definition of
embedded-expression or changing foreach to operate on all expressions plus
an expression list. One of the benifits of the lists I was talking about is
that the expression list becomes a first class construct throughout the
language, not just within the context of foreach, without that you get a
syntactical oddity. Such an oddity may be a conceptual break(it is to me,
but I know it is not to everyone).
FWIW, I also consider the existing array initilizer syntax an oddity. It
simply doesn't exist anywhere else within the langauge and it just seems a
touch wrong to be that way. That, combined with the casting syntax, comprise
most of my complaints about the langauge syntactically, ;).
<snip list ideas> foreach (Customer customer in [yield a for Customer a = GetCustomers() where a.Owed > 0]
Ahh, sounds like Haskell... AFAIK Perl has a similar syntax;
Most functional langauges should. Python does, others do too, I jsut can't
recall off hand which ones(I researched a few dozen langauges
implemetnaitons during my design). (simple examples, madeup syntax). They generate lists and\or enumerators for foreach to consume. There was a considerable thread about this...oh, some time ago. Let me find it.
http://groups.google.com/groups?hl=e...gbl%26rnum%3D2
Its huge, so I do not expect you to read it, however it holds a large part of the discussion we held on these ideas. You're right, it *is* huge; It seems people have been discussing pretty much anything in this thread...
It ranges far and wide. Near the end of one of hte sub threads I wrote much
of a proposal out.
I don't think *I* even read that entire thread, and I must have posted half
of the messages there. One thing that had come up, but certainly hadn't been resolved was creating a list out of two lists contents instead of a list of two lists. However, something to achieve that would solve *this* problem cleanly within the context of a number of other, more general purpose enhancements that maintain the same basic syntactic conventions.
I see. Haskell has a special operator for that, "++" IIRC. But Haskell is all about lists, C# isn't, so I'd say a utility function/class like the "Combine" class above would probably be fine for that (if there was a way to prevent uneccessary boxing); But I expect generics to be modified in that respect in future versions of the framework anyway.
Yes, haskell was one of my sources of inspiration, though python was a more
formative one. I didn't really think haskells syntax would work very well.
I have been thinking about operators, ++ is out of the question of cousre,
but textual operators(like combine<T>()) may be acceptable. Of course, I am
generally pro-textual operators where possible, within reason of course.
Haskell is all about lists, I'll agree, but I think C# *should* be more
about lists, not completly built around them but better support than it has.
Lists are more than common enough to consider it.
Plus, like cody suggested in his original post, it would help turn foreach
into a much stronger tool.
Removing the use of the for loop doesn't sound like a bad idea, ;).
Also, hopefully generics will help fix the boxing issues. Generic
constraints are still pretty limited, conversion and operator constraints
would be a good start. I've been thinking about this idea in more detail and certainly am not set with that syntax. However, at some point I *do* intend to get a compiler working with this, life just hasn't been giving me too many large blocks of free time lately, ;)
I definitely know what you mean... Maybe you should sum up what you have already on a web page. I'd read it. That is, if life will give me a large enough block of time :-)
Hehe. I'll see what I can do. The web itself isn't my strong point, but I've
been meaning to find the time to find some space and put up some projects.
This certainly being one of them.
I have a spec written, if you don't mind word documents. However I'm not
terribly keen on posting binaries to this group, so the web would be easier.
Its just a matter of finding a host, ;). This discussion thread is closed Replies have been disabled for this discussion. Similar topics
reply
views
Thread by Chris McKeever |
last post: by
|
7 posts
views
Thread by winlinchu |
last post: by
|
2 posts
views
Thread by A J Le Couteur Bisson |
last post: by
|
4 posts
views
Thread by Matt Osborne |
last post: by
|
2 posts
views
Thread by TT (Tom Tempelaere) |
last post: by
|
4 posts
views
Thread by Sjoerd |
last post: by
|
reply
views
Thread by Falcula |
last post: by
|
6 posts
views
Thread by John A Grandy |
last post: by
|
8 posts
views
Thread by Bill Butler |
last post: by
| | | | | | | | | | |