Re: How to use ranges?

2015-08-23 Thread Doolan via Digitalmars-d-learn

On Sunday, 23 August 2015 at 13:46:30 UTC, anonymous wrote:

On Sunday 23 August 2015 12:17, Doolan wrote:

And the use of auto everywhere makes it really hard to tell 
what types I should be using for anything. My compiler talks 
about RangeT!(whatever) but you try to use RangeT!(whatever) 
and you find out RangeT is private...


You can use typeof to get the type of a range expression when 
typing it out is impractical/impossible.
What if I want to save a range in a struct? Or is a range more of 
a verb than a noun..?

Can someone give me a short summary of how to use ranges?


I'm not sure what exactly you're looking for. The documentation 
for tee has some example code. How about you show something 
you're having trouble with?
The possibility of using ranges comes up a lot, but here's 
today's example:


I need to compress some data, and luckily it's very suited for 
Running Length Encoding, so I've gone with doing that. 
Occasionally changes need to be made to this data and so rather 
than extracting the data, changing it, and then recompressing it, 
I can just do the equivalent of leaving a post-it note reminding 
the decompression function to sprinkle these changes in after 
decompression. Occasionally, I also need to grab some values out 
of this data without decompressing it, but for every additional 
value I look for I have to search the post-it notes and it gets a 
little fiddly.


So, I vaguely know what ranges are, and I've heard you can chain 
them together, and my code would be much more readable if I could 
cut up access to the data and splice in changes... but I don't 
even know how to define a range of the right type...



And how do they relate to slices? That line is really blurry...


"Slice" is a synonym for what the spec calls a "dynamic array", 
i.e. a structure containing a pointer and a length.


"Slicing" a dynamic array, static array, or pointer produces a 
dynamic array, referencing (not copying) the sliced elements:



int[] d = [1, 2, 3, 4]; /* dynamic array */
int[] slice = d[1 .. 3];
assert(slice == [2, 3]);

d[1] = 20;
assert(slice[0] == 20);

int[4] s = [1, 2, 3, 4]; /* static array */
slice = s[];
assert(slice == [1, 2, 3, 4]);

int* p = [1, 2, 3, 4].ptr; /* pointer */
slice = p[1 .. 3];
assert(slice == [2, 3]);


Note that the source types are different, but slicing them 
yields the same type every time: int[].


Generally, dynamic arrays / slices are random-access ranges. 
Narrow strings (string/wstring/char[]/wchar[]/...) are a 
notable exception to this. They are dynamic arrays of 
UTF-8/UTF-16 code units. But they're not random-access ranges 
of Unicode code units. Instead, they're _forward_ ranges of 
Unicode code _points_ (dchar). They have special range 
primitives that to the decoding.
So slices are random-access ranges... I understand the 
random-access part... but are they inheriting from Range, do they 
just include a Range? Why is int[] an array when I declare, but 
variable[] a Range?? Or isn't it a Range?


Re: How to use ranges?

2015-08-23 Thread Doolan via Digitalmars-d-learn

On Sunday, 23 August 2015 at 10:38:53 UTC, Rikki Cattermole wrote:

On 8/23/2015 10:17 PM, Doolan wrote:
Have a read of: 
https://github.com/rikkimax/twp-d/blob/master/manuscript/content/idioms/ranges.md


Let me know what you think :)


I think I'm a little more confused than before... this says there 
are two kinds of ranges and I thought there were five??


How to use ranges?

2015-08-23 Thread Doolan via Digitalmars-d-learn
I keep running into areas of my code where it looks like I'd 
benefit from using ranges, and then I try to do some range stuff 
and my compiler tells me I'm using the wrong types, or there's 
this problem, or that problem... so I'm scared off and I just 
figure ways to work around using ranges.


I've tried reading the documentation, but for a language priding 
itself on being readable and nice to look at, it really should 
have less complicated docs:


auto tee(Flag!"pipeOnPop" pipeOnPop = Yes.pipeOnPop, R1, R2)(R1 
inputRange, R2 outputRange) if (isInputRange!R1 && 
isOutputRange!(R2, ElementType!R1));
auto tee(alias fun, Flag!"pipeOnPop" pipeOnPop = Yes.pipeOnPop, 
R1)(R1 inputRange) if (is(typeof(fun) == void) || 
isSomeFunction!fun);


(That's fine as secondary information, but this is the heading 
for this function...)


And the use of auto everywhere makes it really hard to tell what 
types I should be using for anything. My compiler talks about 
RangeT!(whatever) but you try to use RangeT!(whatever) and you 
find out RangeT is private...


I don't mean to complain so hard, I obviously like D enough to 
want to use it, just the current amount/layout of documentation 
can be frustrating at times.


Can someone give me a short summary of how to use ranges? And how 
do they relate to slices? That line is really blurry...