I'm back
H. S. Teoh
hsteoh at quickfur.ath.cx
Wed Nov 14 07:29:34 PST 2012
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
More information about the Digitalmars-d
mailing list