I\'ve created a linked list in java using generics, and now I want to be able to iterate over all the elements in the list. In C# I would use yield return insid
"yield return" is a very sophisticated compiler trick. It basically lets you declaratively implement IEnumerable without any of the annoying details of "figuring out" how to build your iterator. The unfortunate thing is that it does not translate into other languages well because very few compilers have such a capability. In some ways "yield return" is as damning as revolutionary.
Basically in C#, the compiler will generate two implementations of IEnumerable and IEnumerator (of T). It does this by basically realizing your "method"'s local variables as instance fields in generated implementation classes as well as examining the frames containing a "yield return" artifact. Once you know this, it should be possible for a well rounded developer to accomplish the same thing explicitly... although not as concisely. To demonstrate, I will CONCAT!
public static Iterable concat(Iterable x, Iterable y)
{
for(T e: x)
{
yield return e;
}
for(T e: y)
{
yield return e;
}
}
// becomes ....
public static Iterator concat_(Iterable x, Iterator y)
{
T e1, e2;
Iterator i1, i2;
Iterator s;
Iterator s4 = new Iterator()
{
public bool hasNext()
{
return false;
}
public E next()
{
throw ... ;
}
public void remove()
{
throw ... ;
}
}
Iterator s3 = new Iterator()
{
Iterator act()
{
if(i2.hasNext())
{
return i2;
}
i2 = y.iterator();
return (s = s4);
}
public bool hasNext()
{
return act().hasNext();
}
public E next()
{
return act().next();
}
public void remove()
{
return i2.remove();
}
}
Iterator s2 = new Iterator()
{
Iterator act()
{
if(i1.hasNext())
{
return i1;
}
i2 = y.iterator();
return (s = s3);
}
public bool hasNext()
{
return act().hasNext();
}
public E next()
{
return act().next();
}
public void remove()
{
return i1.remove();
}
};
Iterator s1 = new Iterator()
{
Iterator act()
{
i1 = x.iterator();
return s = s2;
}
public bool hasNext()
{
return act().hasNext();
}
public E next()
{
return act().next();
}
public void remove()
{
return act().remove();
}
};
s = s1;
return new Iterator()
{
public bool hasNext()
{
return s.hasNext();
}
public E next()
{
return s.next();
}
public void remove()
{
return s.remove();
}
};
}
public static Iterable concat(Iterable x, Iterable y)
{
return new Iterable()
{
public Iterator iterator()
{
return concat_(x, y)
}
};
}
// tada!
If you all will pardon my 3AM pseudo java...