On Fri, Nov 09, 2012 at 02:52:20PM +0100, deadalnix wrote: [...] > OK, seeing your answer and H. S Teoh, I think I badly expressed > myself, because none of you understood. Let's try to explain it > better. > > So back on our joiner range. This range have a source, and will be > given to a consumer as follow : > source -> joiner -> consumer . > > Now let's consider that source provide its own, transient peekFront. > Now joiner can provide both peekFront (based on source.peekFront), > which is transcient and front (based on source.front) which is not > transcient. > > The fact is that both front and peekFront in joiner will have the > same implementation, because the transience of joiner depends of the > transience of its source (like most tranformer ranges). > > Or, with sample code : > > struct Joiner { > R source; > // Fields and range stuffs. > > @property front() { > // Some computation using source.front > } > > @property peekFront() { > // Exact same computation using source.peekFront > } > } > > I hope this make the code duplication more apparent. > > It is impossible for joiner to provide only a version with > peekFront, because joiner.front will be transient, and if it doesn't > provide the version with .peekFront, it can't take advantage of the > improvement that transience can provide.
Hmm, you're right. At first I thought .front would just be a thin wrapper around .peekFront (e.g., return peekFront().dup), but this only works in the source range; joiner wouldn't know how to do that. > So my question is, how this duplication can be avoided ? If it can, > .peekFront is definitively the way to go. But if it can't, this > seems like a really problematic point. My first thought is to use a mixin to generate the function bodies, but that's really ugly and doesn't really avoid duplication in the generated code regardless. :-/ I'll have to think about it more carefully. T -- It is impossible to make anything foolproof because fools are so ingenious. -- Sammy