Early std.crypto

Jonathan M Davis jmdavisProg at gmx.com
Wed Oct 26 12:39:20 PDT 2011


On Wednesday, October 26, 2011 19:00:02 Steve Teale wrote:
> On Wed, 26 Oct 2011 13:01:14 -0400, Jonathan M Davis wrote:
> > Ranges are defined per templates in std.range. isForwardRange,
> > isInputRange, isRandomAccessRange, etc. And it looks like isForwardRange
> > specifically checks that the return type of save is the same type as the
> > range itself. I was thinking that it didn't necessarily require that but
> > that you'd have definite issues having save return a different type,
> > because it's generally assumed that it's the same type and code will
> > reflect that. However, it looks like it's actually required.
> 
> But is it just required by std.range, or is it required at some
> theoretical level by algorithms that can work with ranges as inputs and
> outputs?

It complicates things to allow for the range returned by save not be the same 
type as the original range. It's probably possible to alter isForwardRange to 
allow save to return a different type, but I don't know what all of the side 
effects of such a decision would be. I'm certain however that it would break a 
fair bit of code.

> > What you should probably do is have the result set be an object holding
> > the data but not be a range itself and then overload opSlice to give you
> > a range over that data (as would be done with a container). Then the
> > range isn't in a position where it's trying to own the data, and it's
> > clear to the programmer where the data is stored.
> 
> But in my mind, just from a quick reading of the language definition,
> slices are closely tied to arrays, which as you have already noted, are
> not the best example of a range.
> 
> Are ranges just a library artefact, or are they supported by the
> language. They appear to be recognized by foreach, so if they are
> recognized by D, then we should presumably have operator functions
> opInputRange, opForwardRange, and so on, whatever those terms might mean.

foreach supports the API of an input range: front, empty, and popFront. 
There's no need for overloaded operators of any kind. If you want to overload 
an operator for foreach, then use opApply. foreach is the _only_ place in the 
language that specfically supports ranges.

Arrays are a poor example of ranges because they don't have an obviously 
associated container. A dynamic array is a range over a block of memory that 
the runtime maintains. With a full-blown container such as Array or 
RedBlackTree, it's the container that holds the data, and a range for one of 
them is a range over that container. People tend to think of arrays as being 
containers rather than just slices, so it becomes confusing to people.

It's much easier to properly understand ranges if you think of them as being 
associated with a container like an iterator would be in C++. They don't 
normally own the elements that they're iterating over. When they do, you get 
situations such as input ranges where you can't save them (an input stream 
being a prime example).

> If not, then facilities like std.algorithm should have a warning notice
> like cigarettes that says "this facility may not be usable with POD".

I'm afraid that I don't understand why a warning would be necessary. std.range 
lists the functions that each type of range must implement and it has 
templates for testing whether a particular type implements those functions for 
a given sort of range. I suspect that you're misunderstanding something 
fundamental about ranges.

If you haven't read this article yet - 
http://www.informit.com/articles/printerfriendly.aspx?p=1407357 - I suggest 
that you do. It doesn't entirely match what std.range does (at least as far as 
naming goes) but it does explain the core concepts fairly well and as far as I 
know is the best explanation on ranges that currently exists.

- Jonathan M Davis


More information about the Digitalmars-d mailing list