Jump to page: 1 2 3
Thread overview
why $ is need to access array [negative index]?
Sep 18
mw
Sep 18
mw
Sep 18
mipri
Sep 18
IGotD-
Sep 20
claptrap
Sep 20
IGotD-
Sep 20
claptrap
Sep 18
IGotD-
Sep 18
mw
Sep 18
bachmeier
Sep 18
mw
Sep 18
bachmeier
Sep 18
mw
Sep 18
Ethan
Sep 18
mw
Sep 18
mw
Sep 18
mipri
Sep 18
bachmeier
Sep 18
mw
Sep 18
mipri
September 18
In Python it's such a convenience to be able to access array element from the end:

arr[-1]

in D, we can do that too, but need an extra $: arr[$-1]

I'm porting some code from Python to D:

  int[3] signs;          // sign: -1, 0, 1
  int sign = -1;         // for example
  writeln(signs[sign]);  // Range violation

// Error: array index 18446744073709551615 is out of bounds signs[0 .. 3]

(yes, I know I can use AA, int[int], but it just make things complicated)

Can we have a DIP remove / make optional `$` in this usage?

Thoughts?

September 18
On 9/18/20 3:53 PM, mw wrote:
> In Python it's such a convenience to be able to access array element from the end:
> 
> arr[-1]
> 
> in D, we can do that too, but need an extra $: arr[$-1]
> 
> I'm porting some code from Python to D:
> 
>    int[3] signs;          // sign: -1, 0, 1
>    int sign = -1;         // for example
>    writeln(signs[sign]);  // Range violation
> 
> // Error: array index 18446744073709551615 is out of bounds signs[0 .. 3]
> 
> (yes, I know I can use AA, int[int], but it just make things complicated)
> 
> Can we have a DIP remove / make optional `$` in this usage?
> 
> Thoughts?
> 

I would say no. The indexing code lowers to a machine instruction. Making it so a negative value means something else means every single indexing operation is going to have to check whether it's negative, and if so do something completely different.

You can create your own array type if you want this behavior.

-Steve
September 18
On Friday, 18 September 2020 at 19:53:41 UTC, mw wrote:
> In Python it's such a convenience to be able to access array element from the end:
>
> arr[-1]
>
> in D, we can do that too, but need an extra $: arr[$-1]
>
> I'm porting some code from Python to D:
>
>   int[3] signs;          // sign: -1, 0, 1
>   int sign = -1;         // for example
>   writeln(signs[sign]);  // Range violation
>
> // Error: array index 18446744073709551615 is out of bounds signs[0 .. 3]
>
> (yes, I know I can use AA, int[int], but it just make things complicated)
>
> Can we have a DIP remove / make optional `$` in this usage?
>
> Thoughts?

Array indexes in D are using unsigned integers so negative numbers don't exist. What you are suggesting isn't possible in D. $ is the length of the array so $-1 is correct in this regard and produces a correct positive number given that it is inside the array bounds.


September 18
On Friday, 18 September 2020 at 20:06:01 UTC, Steven Schveighoffer wrote:
>
> I would say no. The indexing code lowers to a machine instruction. Making it so a negative value means something else means every single indexing operation is going to have to check whether it's negative, and if so do something completely different.

Currently we have range check on every single indexing operation already; so the trade-off here is: adding one more check v.s. the convenience it buys.

>
> You can create your own array type if you want this behavior.

September 18
On Friday, 18 September 2020 at 20:08:36 UTC, IGotD- wrote:
> Array indexes in D are using unsigned integers so negative numbers don't exist. What you are suggesting isn't possible in

This is the *consequence* of current design.

We are talking about change the design here.

> D. $ is the length of the array so $-1 is correct in this regard and produces a correct positive number given that it is inside the array bounds.


September 18
On Friday, 18 September 2020 at 19:53:41 UTC, mw wrote:
> In Python it's such a convenience to be able to access array element from the end:
>
> arr[-1]
>
> in D, we can do that too, but need an extra $: arr[$-1]
>
> I'm porting some code from Python to D:
>
>   int[3] signs;          // sign: -1, 0, 1
>   int sign = -1;         // for example
>   writeln(signs[sign]);  // Range violation
>
> // Error: array index 18446744073709551615 is out of bounds signs[0 .. 3]
>
> (yes, I know I can use AA, int[int], but it just make things complicated)
>
> Can we have a DIP remove / make optional `$` in this usage?
>
> Thoughts?

I'm inclined to say typing a single character is not a hardship in exchange for extreme clarity of the code. Keep in mind that Python is not the only language with a negative array index.

For instance, C supports it:

https://stackoverflow.com/questions/3473675/are-negative-array-indexes-allowed-in-c

That's probably the place to look if you want to start, given the relationship of C and D.

Then there's R, for which x[-1] means to drop the first element. That makes a lot of sense if x is treated as a vector of data. Python's usage, on the other hand, is not at all intuitive. Why -4 would mean the fourth to last element is unclear. I believe it was copied from Perl. Ruby does the same thing.

Then there's PHP, which allows you to use a negative array index as an arbitrary reference to an element: x[-2] could be any of the elements.

The strange one is Javascript, which has negative indexes that are actually properties or something like that.

Bottom line is that the Python approach is one of many, it only makes sense if someone tells you what it means, and it saves you a single character in return for less clear code.

As noted, it's really easy to create a struct that operates like Python if you want. That's the beauty of D.
September 18
On Friday, 18 September 2020 at 20:46:00 UTC, mw wrote:
> On Friday, 18 September 2020 at 20:06:01 UTC, Steven Schveighoffer wrote:
>>
>> I would say no. The indexing code lowers to a machine instruction. Making it so a negative value means something else means every single indexing operation is going to have to check whether it's negative, and if so do something completely different.
>
> Currently we have range check on every single indexing operation already; so the trade-off here is: adding one more check v.s. the convenience it buys.

Range checks that never fire because your code isn't buggy
are very friendly to the branch predictor. Negative-indexing
checks are not so friendly.

September 18
On Friday, 18 September 2020 at 20:48:47 UTC, bachmeier wrote:
> I'm inclined to say typing a single character is not a hardship in exchange for extreme clarity of the code. Keep in mind that

It not about saving "typing a single character".

In the example I showed,

signs[sign] = ...;  // the sign can be -1, 0, 1

in D, to write the same code, you have to test the sign and branch:

if (sign >= 0) {
  signs[  sign] = ...;
} else {
  signs[$+sign] = ...;  // remember + here
}


September 18
On Friday, 18 September 2020 at 20:48:47 UTC, bachmeier wrote:
> On Friday, 18 September 2020 at 19:53:41 UTC, mw wrote:
>> In Python it's such a convenience to be able to access array element from the end:
>>
>> arr[-1]
>>
>> in D, we can do that too, but need an extra $: arr[$-1]
>>
>> I'm porting some code from Python to D:
>>
>>   int[3] signs;          // sign: -1, 0, 1
>>   int sign = -1;         // for example
>>   writeln(signs[sign]);  // Range violation
>>
>> // Error: array index 18446744073709551615 is out of bounds signs[0 .. 3]
>>
>> (yes, I know I can use AA, int[int], but it just make things complicated)
>>
>> Can we have a DIP remove / make optional `$` in this usage?
>>
>> Thoughts?
>
> I'm inclined to say typing a single character is not a hardship in exchange for extreme clarity of the code. Keep in mind that Python is not the only language with a negative array index.
>
> For instance, C supports it:
>
> https://stackoverflow.com/questions/3473675/are-negative-array-indexes-allowed-in-c
>
> That's probably the place to look if you want to start, given the relationship of C and D.
>
> Then there's R, for which x[-1] means to drop the first element. That makes a lot of sense if x is treated as a vector of data. Python's usage, on the other hand, is not at all intuitive. Why -4 would mean the fourth to last element is unclear. I believe it was copied from Perl. Ruby does the same thing.
>
> Then there's PHP, which allows you to use a negative array index as an arbitrary reference to an element: x[-2] could be any of the elements.
>
> The strange one is Javascript, which has negative indexes that are actually properties or something like that.
>
> Bottom line is that the Python approach is one of many, it only makes sense if someone tells you what it means, and it saves you a single character in return for less clear code.
>
> As noted, it's really easy to create a struct that operates like Python if you want. That's the beauty of D.

I forgot to add when discussing C, that D already has negative index values, which mean something completely different than Python's usage:

double[] x = [1, 2, 3, 4];
double * y = &(x.ptr)[2];
writeln(y[-2]); // 1

September 18
On Friday, 18 September 2020 at 20:48:47 UTC, bachmeier wrote:
> On Friday, 18 September 2020 at 19:53:41 UTC, mw wrote:
>> In Python it's such a convenience to be able to access array element from the end:
>>
>> arr[-1]
>>
>> in D, we can do that too, but need an extra $: arr[$-1]
>>
>> I'm porting some code from Python to D:
>>
>>   int[3] signs;          // sign: -1, 0, 1
>>   int sign = -1;         // for example
>>   writeln(signs[sign]);  // Range violation
>>
>> // Error: array index 18446744073709551615 is out of bounds signs[0 .. 3]
>>
>> (yes, I know I can use AA, int[int], but it just make things complicated)
>>
>> Can we have a DIP remove / make optional `$` in this usage?
>>
>> Thoughts?
>
> I'm inclined to say typing a single character is not a hardship in exchange for extreme clarity of the code.

The hardship isn't typing a single character, but requiring an
explicit test to determine whether you should index with or
without that single character.

Consider:

  int ex(int i) {
      immutable int[3] ns = [1, 2, 3];
      if (i < 0) {
          return ns[$+i];
      } else {
          return ns[i];
      }
  }

  void main() {
      import std.stdio, std.range, std.algorithm;
      iota(3)
          .map!(n => n - 1)
          .map!ex
          .each!writeln;
  }

In Python you can calculate an index on a numeric plane that
includes negative numbers and then use it; in D you have some
syntax to conveniently refer to the size of the array.
« First   ‹ Prev
1 2 3