Any chance to call Tango as Extended Standard Library

dsimcha dsimcha at yahoo.com
Mon Jan 19 12:35:45 PST 2009


== Quote from Jason House (jason.james.house at gmail.com)'s article
> Andrei Alexandrescu wrote:
> > Jason House wrote:
> >> Andrei Alexandrescu wrote:
> >>
> >>> Speed is a small part of the equation, in fact a perk only. Ranges
> >>> are composable; you can combine them to e.g. do parallel iteration
> >>> over two ranges. Ranges really open std.algorithm to all data
> >>> structures. I find opApply incredibly obtuse and fostering bad
> >>> design. I wish it goes away.
> >>
> >> I'd really hate to see opApply go away.  I'm glad Walter says it's
> >> sticking around ;)
> >
> > I know. Its popularity is part of what makes it dangerous. It's to good
> > programming what fast food is to food :o).
> >
> >> opApply is really nice in how *simple* it is to write.  I think it's
> >> possible to use druntime's fibers to convert an opApply
> >> implementation into a range implementation.  It'd be an interesting
> >> challenge to write a templated struct that handles all of this.  Once
> >> that is done, maybe someone could discuss using Fibers to implement
> >> opApply in D2.  I suspect the code inside an opApply would only
> >> change a little bit and it'd allow iteration over multiple "ranges"
> >> at the same time.
> >
> > But that's making the mythical bear dance. Iterating over multiple
> > ranges is only one example. How do you feed one range to another range
> > with opApply?
> >
> > At the end of the day, if what you want is to iterate, you need to
> > define what the state of iteration is, how to make a step, and how to
> > get to the current element being iterated. That is a good design, not
> > opApply and fibers!
> >
> >
> > Andrei
> Are you saying that nobody should ever use coroutines?  A coroutine version of
opApply keeps the state of iteration as part of the natural flow of making steps
and getting the current element being iterated.  Let's look at various
implementation examples:
> current opApply style:
> int opApply(int delegate( ref T ) dg){
>   int unknown;
>   foreach(i; 0..length){
>     unknown = dg(arr[i]);
>     if (unknown != 0)
>       return unknown;
>   }
>   return 0;
> }
> With coroutine:
> void iterateOverArray(T)(T[] arr){
>   foreach (i; 0..arr.length)
>     yield(arr[i]);
> }
> ... or maybe something more complex like the following is required?
> void iterateOverArray(T)(T[] arr){
>   foreach (i; 0..arr.length){
>     yield!("empty") = false;
>     yield!("next") = arr[i];
>   }
>   yield!("empty") = true;
> }
> A range-based struct:
> struct arrayIterator(T){
>   int _i;
>   T[] _arr;
>   this(T[] arr){
>     arr = _arr;
>   }
>   T next(){
>     return arr[i++];
>   }
>   bool empty{
>     return i<_arr.length;
>   }
> }
> Here are the line counts for the above implementations:
> current opApply style: 9
> coroutine with implied empty: 4
> coroutine with explicit empty: 7
> range-based: 13
> Which one would D users want to write?  Personally, I want the coroutine with
implied empty.  I could see having to explicitly state empty or at least specify
when it changes.  If the above examples don't convince you that D should consider
allowing alternate implementations to basic range structs, then I'll stop trying
to convince you.

Yeah, but we also want decent performance and even compared to opApply,
coroutines/fibers are slow as molasses in January at the North Pole during the
last Ice Age.



More information about the Digitalmars-d mailing list