On Wed, Nov 14, 2012 at 12:51:45AM +0100, deadalnix wrote: > Le 13/11/2012 20:13, Jonathan M Davis a écrit : > >On Tuesday, November 13, 2012 09:45:17 H. S. Teoh wrote: > >>Unfortunately, using ranges in their most general sense is looking > >>like a pipe dream to me right now, and I'm ready to just move on. > > > >The reality of the matter is that there are limits to any > >abstraction. In order to make it take more use cases and situations > >into account, it must become increasingly complicated, and eventually > >the abstraction becomes complicated enough that it's hard to use for > >even basic cases.
In that case, I argue that the abstraction is a leaky one, and needs to be improved/replaced. A successful abstraction, as deadalnix stated, is one that has a solid, consistent core, and which is extensible by user code to handle more complicated stuff. As the saying goes: "simple things should be simple, and hard things should be possible". When simple things are hard, and hard things are impossible, e.g., supporting transience is hard, or outright impossible, then you know something is fundamentally wrong with the design. At this point it's probably futile, but I'll say it anyway: I think the *idea* of ranges is a very powerful one. It has the potential to be universally applicable to all linear access algorithms. The disappointment lies not in the idea, but in its implementation. The implementation failed to take into account the subtle difference between reference semantics and value semantics. This shortcoming is not something inherent in the idea of ranges itself, but rather in the range-based algorithms that failed to take this into account. A truly generic algorithm will make no further assumptions than what is absolutely essential for its operation. For example, joiner does not *need* to assume the persistence of .front, yet the current implementation does. To me, this is sloppy programming. An algorithm that can be implemented without making such additional assumptions, shouldn't. OTOH, an algorithm that *does* require such an assumption needs to state it up front in some way, either by requiring something labelled as a non-transient range, or by an in-contract, or some such. Generic algorithms and unstated assumptions simply don't mix, because inevitably somebody will call it with the "wrong" range and things will break. Attempting to conflate the additional assumption (persistence of .front) with orthogonal properties of ranges is merely glossing over the real issue. But since this isn't going to be fixed properly, then the only solution left is to arbitrarily declare transient ranges as not ranges (even though the concept of ranges itself has no such implication, and many algorithms don't even need such assumptions), and move on. We will just have to put up with an inferior implementation of std.algorithm and duplicate code when one *does* need to work with transient ranges. It is not a big loss anyway, since one can simply implement one's own library to deal with this issue properly. > Let me disagree. As stated before, I never used moveXXX in my code. > That doesn't mean it is useless, but that you can definitively work > with an abstraction without messing around with all possible « > extensions ». > > I'd argue that this is the key to successful abstraction : a solid > core, a possibility for extension and knowledge of such extension > being optional. [...] +1. T -- Indifference will certainly be the downfall of mankind, but who cares? -- Miquel van Smoorenburg