Early std.crypto

Jonathan M Davis jmdavisProg at gmx.com
Tue Oct 25 23:45:58 PDT 2011


On Wednesday, October 26, 2011 06:28:52 Steve Teale wrote:
> > An easy test is that if the interface takes a T[] as input, consider a
> > range instead. Ditto for output. If an interface takes a File as input,
> > it's a red flag that something is wrong.
> 
> I have a question about ranges that occurred to me when I was composing a
> MySQL result set into a random access range.
> 
> To do that I have to provide the save capability defined by
> 
> R r1;
> R r2 = r1.save;
> 
> Would it harm the use of ranges as elements of operation sequences if the
> type of the entity that got saved was not the same as the original range
> provider type. Something like:
> 
> R r1;
> S r2 = r1.save;
> r1.restore(r2);
> 
> For entities with a good deal of state, that implement a range, storing
> the whole state, and more significantly, restoring it, may be non-
> trivial, but saving and restoring the state of the range may be quite a
> lightweight affair.

It's likely to cause issues if the type returned by save differs from the 
original type. From your description, it sounds like the range is over 
something, and it's that something which you don't want to copy. If that's the 
case, then the range just doesn't contain that data. Rather, it's a view into 
the data, so saving it just save that view.

The fact that arrays are currently the most used example of ranges definitely 
makes them more confusing IMHO, since people often think of ranges as 
containers, whereas ranges aren't. And really, dynamic arrays in D _aren't_ 
containers. No dynamic array actually owns its elements. The runtime owns it, 
and dynamic arrays are just ranges over that data.

It's easier to understand when you think about a container, such as vector 
type (e.g. std.container.Array) or a linked list. The container holds the 
data. The container is _not_ a range. A range is a view of that data. So, 
popping elements off of the range has no effect on the original container - the 
same goes with many range-based functions. As long as the elements in the 
range aren't mutated or rearranged, the elements in the container are 
unaltered. So, calling save on a range just gives you a copy of that view of 
the container, allowing you to alter the range and still have that original 
view of the container.

> I'm also puzzled by the semantics of the random access range.
> 
> If I restrict myself to indexing into the range, then things are fine.
> 
> auto x = r[0];
> x = r[10];
> x = r[0];
> 
> But if I slip in a few popFront's, then presumably x = r[0] will give me
> a different result.
> 
> This just makes me slightly uneasy.

r[0] _is_ r.front, so of course popFront would change what r[0] is. You're 
consuming the range as you pop elements off of its front. So, if you do 
_anything_ which alters a range (rather than its elements), at least some of 
(if not all of) the indices in a random access range change. The reason that 
this is making you uneasy is likely at least partially because of the fact 
that you're probably thinking about arrays and how they're used rather than 
thinking more abstractly about ranges. Arrays are really a bad example of 
ranges, in spite of the fact that they are unfortunately, our most common 
example of ranges at this point.

- Jonathan M Davis


More information about the Digitalmars-d mailing list