November 09, 2006
Hmm, as far as I understand, the non-inclusive slice avoids massive '+1' appearings in source.

For example (slice five elements]:

uint size = 5;
data[head..head + size] //is better than data[head..head + size + 1] for inclusive
slice

But, there are better syntax available:

[2..5] means 2,3,4,5 (inclusive slice)
[2..:5] means 'take five elements, first is at index 2', to avoid '+1' problem

So, example becomes:

uint size = 5;
data[head..:size] //good, isn't it ?

---
CON: making '..' slice inclusive breaks a lot of code :(

November 09, 2006
Don Clugston wrote:
> rm wrote:
> 
>>
>> well if compiler issues are no issues, than the most explicit would be:
>>
>> array[1 .. 5] == 1,2,3,4,5
>> array]1 .. 5] ==   2,3,4,5
>> array[1 .. 5[ == 1,2,3,4
>> array]1 .. 5[ ==   2,3,4
>>
>> roel
> 
> 
> so a[b[1..5].length]
> 
> would become a[b]1..4[.length]
> ??

Nice one.

actually I think it would be

a[b]0..4[.length]

I think one big killer is that syntax highlighting would be darn near impossible. Just try to get the brace matching working.


 .--------------.
 | .----.       |
 | |    |       |
a[b]0..4[.length]


same for the math version

 .--------------.
 | .----.       |
 | |    |       |
a[b[1..5).length]

[ matching ) ??

or what about eyeball parsing?

foo( a[i..2), fn(a2..i]);

what is that supposed to be?
it is darn close to:

foo( a[i..2]), fn(a[2..i]);

and both would compile.

November 09, 2006
Don Clugston wrote:
> rm wrote:
>> Ary Manzana wrote:
>>> Mike Parker escribió:
>>>> Alexander Panek wrote:
>>>>> I'd really like to have a distinction between exclusive and inclusive slicing. Maybe '..'(inclusive) and '..-'(exclusive) or similar, with '..' => '..-'. Not *that* beautiful, though .. maybe someone has a better suggestion.
>>>>>
>>>>
>>>> What about leaving ... as is and using ..+, or ...+, for inclusive?
>>>
>>> I think the best approach is to use standard mathematical notation:
>>>
>>> array[1 .. 5] == 1, 2, 3, 4, 5
>>> array(1 .. 5] == 2, 3, 4, 5
>>> array[1 .. 5) == 1, 2, 3, 4
>>> array(1 .. 5) == 2, 3, 4
>>>
>>> There's no confusion there when you know mathematical ranges. The only problem is it's a confusion to the compiler... maybe?
>>
>> well if compiler issues are no issues, than the most explicit would be:
>>
>> array[1 .. 5] == 1,2,3,4,5
>> array]1 .. 5] ==   2,3,4,5
>> array[1 .. 5[ == 1,2,3,4
>> array]1 .. 5[ ==   2,3,4
>>
>> roel
> 
> so a[b[1..5].length]
> 
> would become a[b]1..4[.length]
> ??

I don't know :-)

In the case you give .. I'd say it's still possible to find out the correct sequencing, something like: ok, I found a range indicator (being  ..), that should be surrounded by 2 two [] characters. Now, whether that's efficient, ... , that's another question.

But I'm sure there are cases to be found that are always ambiguous.

roel
November 09, 2006
Nikita Kalaganov wrote:
> Hmm, as far as I understand, the non-inclusive slice avoids massive '+1'
> appearings in source.
> 
> For example (slice five elements]:
> 
> uint size = 5;
> data[head..head + size] //is better than data[head..head + size + 1] for inclusive
> slice
> 

Wouldn't that be -1? But the point stands.

Also how do you get a 0 length slice with inclusive?

exclusive

data[0..0].length == 0;

inclusive

data[0..0].length == 1;


> But, there are better syntax available:
> 
> [2..5] means 2,3,4,5 (inclusive slice)
> [2..:5] means 'take five elements, first is at index 2', to avoid '+1' problem
> 
> So, example becomes:
> 
> uint size = 5;
> data[head..:size] //good, isn't it ?
>

I'd go with [start->length] but thats just me.
November 09, 2006
On Thu, 09 Nov 2006 06:52:40 +0200, %u <trevorparscal@hotmail.com> wrote:

> I'm learning ruby right now, and I noticed they use a very cool syntax for ranges.
>
> 0..5 means 0, 1, 2, 3, 4, 5
> 0...5 means 0, 1, 2, 3, 4
>
> The current array slicing is useful half the time and a pain in the arse the
> other half, so I was wondering if anyone else has mentioned this idea for D
> before...
>
> - Trevor

I wouldn't mind that the following would be possible in D:

1 .. 3 = 1, 2

1 ... 3 = 1, 2, 3

To me that would be easy to remember, and not too error-prone. But that's just me.
Then it would be fun to take turns with D and Ruby! :) Well, actually I think it would be fun even now because '..' means different range in D and Ruby.

But if '...' is considered too similar with '..', how about the following?

1 -> 3 = 1, 2, 3
November 09, 2006
%u wrote:
> I'm learning ruby right now, and I noticed they use a very cool syntax for ranges.
> 
> 0..5 means 0, 1, 2, 3, 4, 5
> 0...5 means 0, 1, 2, 3, 4
> 
> The current array slicing is useful half the time and a pain in the arse the
> other half, so I was wondering if anyone else has mentioned this idea for D
> before...
> 
> - Trevor

I hope you don't mind, but I'm just thinking aloud here.

I like the idea, and it has been brought up before on multiple occasions.  But I don't think the syntax is going to stand up to scrutiny for a lot of reasons (many were already voiced in earlier posts). My feeling is that it's not clearly distinguished from ".." which is important since ".." only ever appears within the same context.

Something that triggers a "create range" expression might be clearer:

auto myRange = @[0..10];

...distinguishing from uint and int ranges is another problem.  The actual "type" installed is another, which leads me into the main thrust of this post: I don't think the creation syntax is the main stumbling block for the inclusion of a range type into D.

Rather, I feel that the problem is: how would any range type be implemented under-the-hood, let alone it's construction syntax?  What would it need to be?

I can't help but see it as a pseudo-array type, in order to allow for concatenation, slicing, array operations (when and if they're implemented), and iteration to all behave correctly.

// assuming ranges play fair with arrays, how would these work?
foreach(x; myRange){}
myRange[1..10];
myRange.dup;
myRange.length;
myRange ~= anotherRange;

The only way to satisfy all of the above cleanly, is as a library type that masquerades as an array.  Something like a templated struct could do the job nicely, and would cover more range types than just integer sequences.  In essence, I think the need for a range type w/array semantics, is one-and-the-same with the need for an iterator implementation.  They're just two different flavors of the same thing: one iterates an actual data set (which built-in arrays do implicitly), the other pulls values out of thin air.

-- 
- EricAnderton at yahoo
November 09, 2006
%u skrev:
> I'm learning ruby right now, and I noticed they use a very cool syntax for ranges.
> 
> 0..5 means 0, 1, 2, 3, 4, 5
> 0...5 means 0, 1, 2, 3, 4
> 
> The current array slicing is useful half the time and a pain in the arse the
> other half, so I was wondering if anyone else has mentioned this idea for D
> before...
> 
> - Trevor

My €0.02:

0..5 should mean 0,1,2,3,4.
Because it does not break existing code.

0...5 should be 0,1,2,3,4,5.
All other suggestion I have seen looks contrived to me. .. and ... look obviously connected somehow, and logically "... takes it one step further than ..". Perfect or not, I have not seen any suggestion that beats it.


I also like to yet again say that having ranges as a type that can easily be based around would be neat.

bool checkAge(int age, int min, int max) { ... }
auto ok = checkAge(bar, 18, 25);
or
bool checkAge(int age, int$ range) { ... }
auto ok = checkAge(bar, 18...25);

Well how to denote a range type, is something I have not figured out yet. So I went for a $ suffix in the example.


As an extension, sets is just as useful!

int<> myFriendsAges = <18, 25, 21>;
bool foo = allAgesInRangeOver21(myFriendsAges);


And imagine slicing an array with a set!
Person[] primePersons = allPersons[<2,3,5,7,11>];


// Fredrik Olsson
November 09, 2006
rm wrote:
> %u wrote:
>> I'm learning ruby right now, and I noticed they use a very cool syntax for ranges.
>>
>> 0..5 means 0, 1, 2, 3, 4, 5
>> 0...5 means 0, 1, 2, 3, 4
>>
>> The current array slicing is useful half the time and a pain in the arse the
>> other half, so I was wondering if anyone else has mentioned this idea for D
>> before...
>>
>> - Trevor
> 
> in python you have a slice object, which you can pass like you would pass a range, works beautifully, is more powerful and in my eyes less error prone than .. or ... and I think ruby must change it <g> because ... has one point more than .. but one element less ... (these latest 3 points indicate I could go on and on ... :-) )
> 
> roel

hmmm, replying to my own messages :-)
slicing in python:

>>> str = "hello world from roel"
>>> s = slice(3,10,2) # start,stop(excluding)[,step]
>>> str[s]
'l ol'
>>> s = slice(1,12,2)
>>> str[s]
'el ol '
>>> s = slice(1,14,2)
>>> str[s]
'el ol r'

so it's just a type (and yes python is a typed language :-) )
I guess it's possible to create a type Slice in D and overload the opIndex operator of another type to accept a Slice type as argument.


November 09, 2006
> I also like to yet again say that having ranges as a type that can easily be based around would be neat.
> 
> bool checkAge(int age, int min, int max) { ... }
> auto ok = checkAge(bar, 18, 25);
> or
> bool checkAge(int age, int$ range) { ... }
> auto ok = checkAge(bar, 18...25);
> 
> Well how to denote a range type, is something I have not figured out yet. So I went for a $ suffix in the example.

bool checkAge(int age, int..int range) { ... }
?
November 10, 2006

Pragma wrote:
> ...
> 
> The only way to satisfy all of the above cleanly, is as a library type that masquerades as an array.  Something like a templated struct could do the job nicely, and would cover more range types than just integer sequences.  In essence, I think the need for a range type w/array semantics, is one-and-the-same with the need for an iterator implementation.  They're just two different flavors of the same thing: one iterates an actual data set (which built-in arrays do implicitly), the other pulls values out of thin air.

Which brings up an interesting idea...

> auto range = new Range!(int)(0,10,2); // 0-10 with 2 step
> auto evens = someArray[range]; // extract even elements

Would be really cool since you could fiddle with the range to get exactly the set of elements you want, and then extract them all in one pass.  But if you're going to do that, why not just allow the "range" bit be any old iterator that iterates over keys?

> auto range = AllPeople.marriedIterator;
> auto shackled = AllPeople[range];

Just a thought :3 Maybe we should just MAKE a library implementation of a range, hand it to Walter and say "let's make this standard".

We can then write mixins to be used by library code for using ranges inside of opIndex; it should be possible to express opIndex(range) in terms of opIndex(key).  Maybe if we can a standard iterator interface/base class/whatever, we can do the same to allow for slicing using an interator.

(Also thinking out loud...)

	-- Daniel

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/