Skip to content

RFC: Python-like slices in vec #1799

New issue

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

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

Already on GitHub? Sign in to your account

Closed
nikomatsakis opened this issue Feb 10, 2012 · 22 comments
Closed

RFC: Python-like slices in vec #1799

nikomatsakis opened this issue Feb 10, 2012 · 22 comments
Labels
A-frontend Area: Compiler frontend (errors, parsing and HIR) C-enhancement Category: An issue proposing an enhancement or a PR with one.
Milestone

Comments

@nikomatsakis
Copy link
Contributor

I would like to modify the vector (and string, I suppose) slicing routines to be more "Python-like". This means that they are more lenient of invalid indices and they consider negative numbers to count from the right.

All in all I propose six functions:

vec::islice(v, from, to) // equivalent to v[from:to] in Python
vec::islice_from(v, from) // equivalent to v[from:] in Python, or vec::slice(v, from, vec::len(v))
vec::islice_to(v, to) // equivalent to v[:to] in Python, or vec::slice(v, 0, to)

vec::uslice(v, from, to)
vec::uslice_from(v, from, to)
vec::uslice_to(v, from, to)

The i family accepts signed integers: negative inputs are considered as counting from the right. The u family takes unsigned integers. All of them are tolerant of invalid indices, returning empty list rather than failing, as Python does. In my experience this is usually what you want.

@BrendanEich
Copy link

+1 all around. Thanks,

/be

Niko Matsakis wrote:

I would like to modify the vector (and string, I suppose) slicing routines to be more "Python-like". This means that they are more lenient of invalid indices and they consider negative numbers to count from the right.

All in all I propose six functions:

 vec::islice(v, from, to) // equivalent to v[from:to] in Python
 vec::islice_from(v, from) // equivalent to v[from:] in Python, or vec::slice(v, from, vec::len(v))
 vec::islice_to(v, to) // equivalent to v[:to] in Python, or vec::slice(v, 0, to)

 vec::uslice(v, from, to)
 vec::uslice_from(v, from, to)
 vec::uslice_to(v, from, to)

The i family accepts signed integers: negative inputs are considered as counting from the right. The u family takes unsigned integers. All of them are tolerant of invalid indices, returning empty list rather than failing, as Python does. In my experience this is usually what you want.


Reply to this email directly or view it on GitHub:
#1799

@BrendanEich
Copy link

Oops, replied to the list. For the record, +1 all around.

/be

@killerswan
Copy link
Contributor

Looks good. Why not make islice into slice?

@brson
Copy link
Contributor

brson commented Feb 10, 2012

I agree with killerswan. Just call islice slice. I'm not crazy about accepting bad input though.

@marijnh
Copy link
Contributor

marijnh commented Feb 10, 2012

I'd make the unsigned-integer version fail on out-of-range indices. So you'd have the choice of a liberal version and a strict version.

Also, yes, name one of them simply slice.

@nikomatsakis
Copy link
Contributor Author

I'd be ok with uslice being precisely what slices are today (strict as can be) and slice being the convenient, Python-like form.

@qwertie
Copy link

qwertie commented Feb 10, 2012

As a general principle, I think that for performance reasons, there should always be a "never-fails" version of all important language primitives. The reason is that it is common for developers to want a version that can't fail, and if the language/library doesn't offer one then the developer has to write a function to do it himself. Then what happens is, the developer checks the arguments, and then the compiler or std lib does exactly the same check a second time, which is just wasteful in an inner loop. Plus, the compiler has to spend a little extra time inlining this little function everywhere.

Of course, a version that fails on unexpected input is equally useful and should also be provided. IMO, then, there should be three slice functions: two fast (unsigned with fail, unsigned without fail) and one slower and more flexible (python style). But then you would have more arguing to do about naming. Mind you, I didn't catch how slices work in Rust -- I'm assuming it's like Go where a slice is merely a pointer and a length, no copying involved. If a slice actually copies the whole range then it was silly of me to worry about the speed of the range checks.

@Dretch
Copy link
Contributor

Dretch commented Feb 11, 2012

One thing I like about python is that it has a single slice operator (albeit with optional arguments). I find an API made up of lots of very similar functions to be confusing.

@bstrie
Copy link
Contributor

bstrie commented Feb 13, 2012

Python's slicing mechanism really is one of my favorite aspects of the language. +1

Add my voice to the chorus of those who'd love to see the v[from:to] syntax be supported.

It looks like Go handles this by making slices a separate type entirely: http://blog.golang.org/2011/01/go-slices-usage-and-internals.html

This issue is also related to #555.

@nettok
Copy link

nettok commented Feb 14, 2012

Don't forget about Python's extended slice notation v[from:to:step].

With this is possible to reverse a list doing this v[::-1].

@darkf
Copy link
Contributor

darkf commented Feb 14, 2012

+1 for [from:to:step] syntax.

@killerswan
Copy link
Contributor

Why not just call vec::reverse?

@nettok
Copy link

nettok commented Feb 14, 2012

vec::reverse would be equivalent to v[::-1], but it is just a subset of what would be possible with this notation.

For example, take only pair indices v[::2], and reversed pair indices v[::-2], etc...

@graydon
Copy link
Contributor

graydon commented Feb 15, 2012

There was some gesture towards supporting this long ago, but I removed it out of lack of effort. If someone wants to champion it, I'm fine with that.

@killerswan
Copy link
Contributor

@nikomatsakis, slice_to and slice_from could also be called take and drop, instead.

@amunra
Copy link

amunra commented Mar 17, 2012

+1

I'd love to see the slicing notation

[from:to:step]

Makes for very intuitive code

@ghost ghost assigned graydon Apr 12, 2012
@catamorphism
Copy link
Contributor

Underway, but not for 0.3 and possibly not with step, as per @graydon .

@nikomatsakis
Copy link
Contributor Author

withdrawing in favor of a newer proposal based on our current slices

@bstrie
Copy link
Contributor

bstrie commented Jun 1, 2012

I take it that means this proposal:

http://smallcultfollowing.com/babysteps/blog/2012/05/14/vectors/

Not sure if there's an issue for it yet.

@glyn
Copy link
Contributor

glyn commented Oct 14, 2020

Meanwhile, see https://crates.io/crates/slyce.

@evbo
Copy link

evbo commented Feb 10, 2024

where did this end up? It'd be really useful if slice ranges in Rust were more forgiving, like in Python. Does that feature exist for avoiding errors like?:

range end index 100 out of range for slice of length 39

@glyn
Copy link
Contributor

glyn commented Feb 12, 2024

where did this end up? It'd be really useful if slice ranges in Rust were more forgiving, like in Python. Does that feature exist for avoiding errors like?:

range end index 100 out of range for slice of length 39

slyce, linked above, is completely forgiving (because of the nature of its usage in the upcoming JSONPath RFC).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-frontend Area: Compiler frontend (errors, parsing and HIR) C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

No branches or pull requests