Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

more powerful range operations #4933

Closed
SleepyRoy opened this issue May 17, 2020 · 9 comments
Closed

more powerful range operations #4933

SleepyRoy opened this issue May 17, 2020 · 9 comments
Labels
Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one.

Comments

@SleepyRoy
Copy link
Member

SleepyRoy commented May 17, 2020

I propose V provides more powerful range operations. More specific,

// proposal A. minus position (meaning from back to front)
a[-1]  // the last element, same as a[a.len-1]
a[-2]  // the second from last, same as a[a.len-2]

// proposal B. interval - start_pos..interval..end_pos
a[2..1..5]  // same as a[2..5] so actually no need to write like this
a[2..2..7]  // a[2], a[4], a[6]
a[2..-2..7]  // interval can be minus, meaning reverse order so a[6], a[4], a[2]
a[..-1..]  // same as a.reverse() 

// proposal C. nothing means itself (technically, on this dimension)
a[ ]  // same as a[..]

// proposal D. enable all operations for ndim>1 arrays
a[ , , ..-1.., ..-1..]  // reverse on third and fourth dim (useful in, e.g. deep learning)  

Also, Q&A (some personal views):
a. Now a..b means [a, b) instead of [a, b], is this nice?
I think yes, [a, b) is sometimes more elegant - 0..a.len better than 0..a.len-1.

b. About proposal B, why not start_pos..end_pos..interval?
This comes from V's len=2 range op (..).
Think about reverse operation as an example, if so, then we have to write

a[....-1]  // not elegant!

In contrast, start_pos..interval..end_pos doesn't have this issue - omitting interval means interval=1, so there's no point in writing a[....-1]. Just write a[..-1] instead.

c. Why proposal C? Just for less keyboard pressing?
No. V has len=2 range op (..) rather than len=1 (e.g. :) so omitting unnecessary ones helps keep elegant. Think about an dim=10 array.

a[.., .., .., .., .., .., .., -1, .., ..]  // really bad!
a[ , , , , , , , -1, , ]  // at least better
@SleepyRoy SleepyRoy added the Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one. label May 17, 2020
@SleepyRoy SleepyRoy changed the title more range operations more powerful range operations May 17, 2020
@JalonSolov
Copy link
Contributor

I like A, but... if a[1] is the 2nd element in the array, but a[-1] is the last, it almost seems like an "off-by-1" problem.

I think B is a bit confusing, and could be error-prone. At the least, it will take a while to get the syntax correct.

C... it just saves 2 characters. I don't see the need.

D same as B.

Just my opinions.

@nedpals
Copy link
Member

nedpals commented May 18, 2020

Among the four proposals, I would rather see Proposal A be implemented.

@medvednikov
Copy link
Member

Negative indexing gets suggested a lot. It will never be implemented due to being too bug prone. An unexpected value can mess up the entire program.

@iredmail
Copy link
Contributor

iredmail commented May 18, 2020

  • It's good to have proposal A but not required. a.len-1 is ok, but -1 is much easier to read and understand.
  • Others are hard to read and understand at a glance, so better not implement them all.

@SleepyRoy
Copy link
Member Author

SleepyRoy commented May 18, 2020

I think one possible way to prevent error-prone negative index is using another char indicating negative (better say, indicating 'from back to front'), e.g. # (maybe not good, but we could discuss and find good one).

And I think it's better to explain my proposals with some real cases.

CASE a. this_is_a_var is a matrix (i.e. 2D array) and we want the region of last 10 rows and last 10 cols.

result_var := this_is_a_var[this_is_a_var.len-10..][this_is_a_var.len-10..]    // now
result_var := this_is_a_var[#10.., #10..]   // proposal

CASE b. this_is_another_var is a 4D array and we want even rows and even cols from 3rd and 4th dimension, with reverse order (e.g. convolution needs such operation).

// now
result_var := generate_array_with_zeros(this_is_another_var.len[0], this_is_another_var.len[1], (this_is_another_var.len[2] + 1) / 2, (this_is_another_var.len[3] + 1) / 2)
for i in 0..result_var.len[2]  {
    for j in 0..result_var.len[3] {
        result_var[..][..][i][j] = this_is_another_var[..][..][2*i][2*j]
    }
}
reverse_array_on_dim(result_var, 2, 3)

result_var := this_is_another_var[.., .., ..#2.., ..#2..]    // proposal
result_var := this_is_another_var[ , , ..#2.., ..#2..]    // proposal - even this

BTW, start_pos-interval-end_pos (or start_pos-end_pos-interval) is common in scientific computing languages, e.g.

# Python
arr[1:10:2]    # arr[1], arr[3], arr[5], arr[7], arr[9]
% MATLAB
for i = 1:2:100  
    disp(i)    % print 1,3,5,...,99
end

@JalonSolov
Copy link
Contributor

That makes more sense in context.

@dhonx
Copy link
Member

dhonx commented May 18, 2020

I only like proposal A

@sheerun
Copy link
Contributor

sheerun commented Jun 2, 2020

I like ruby ranges, very few cases: x[1], x[-1], x[1..-1] (all but first), z[0..-2] (all but last)

@nedpals
Copy link
Member

nedpals commented Jun 2, 2020

For those who want a fine-grained range generation, theres https://github.com/Delta456/range

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Feature/Enhancement Request This issue is made to request a feature or an enhancement to an existing one.
Projects
None yet
Development

No branches or pull requests

7 participants