Skip to content

Length inferred a[3:end]? #824

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

Open
dlfivefifty opened this issue Sep 18, 2020 · 9 comments
Open

Length inferred a[3:end]? #824

dlfivefifty opened this issue Sep 18, 2020 · 9 comments
Labels
arrays AbstractArray interface and array operations feature features and feature requests

Comments

@dlfivefifty
Copy link
Member

I'm wishing to do things like a[3:end] but have it return an SVector. I found a way to do this:

julia> a = SVector(1,2,3,4)
4-element SArray{Tuple{4},Int64,1,4} with indices SOneTo(4):
 1
 2
 3
 4

julia> a[3:end] # Length not inferred
2-element Array{Int64,1}:
 3
 4

julia> reverse(reverse(a)[SOneTo(2)]) # Length inferred
2-element SArray{Tuple{2},Int64,1,2} with indices SOneTo(2):
 3
 4

Is there an establish idiom for this? Would it be worth adding this to the package say as a special type (a[SToEnd(3)])?

@mateuszbaran
Copy link
Collaborator

A possible solution was discussed in #703 . For now I would probably just convert a to tuple, select the range you want and convert back to SVector: SVector(a.data[3:end]). It gets more problematic for matrices though.

@dlfivefifty
Copy link
Member Author

Ah good point.

@c42f
Copy link
Member

c42f commented Sep 21, 2020

I agree this would be nice.

In #703 we thought ranges which are conceptually derived from axes(a) could be made static. So related functions like firstindex and lastindex could return StaticInteger.

So 3:end would have a static integer as the last part of the range. Then to have a[3:end] work like you want, we'd further need the static integers to be "contagious" enough that :(::Int, ::StaticInteger) returns a static range rather than a normal range. It's this final part which is slightly iffy: you generally don't want static-ness to be contagious when it'd lead to type instability. But maybe it'd be fine.

@c42f c42f added arrays AbstractArray interface and array operations feature features and feature requests labels Sep 21, 2020
@andyferris
Copy link
Member

That would work - but it's still not perfect in the case tht the Int is not a known constant. (I almost want the ability to ask if a variable is inferred as Const or not - it's a bit of a generalization of the literal_pow type of stuff).

@c42f
Copy link
Member

c42f commented Sep 22, 2020

That would work - but it's still not perfect in the case tht the Int is not a known constant.

Yep that's what I meant with the obscure comment about contagiousness and type stability :)

I almost want the ability to ask if a variable is inferred as Const or not - it's a bit of a generalization of the literal_pow type of stuff

This is kinda bad in the same way that using return_type is discouraged: it makes the optimizer decisions affect the types the user sees. Actually I think this can be ok when the resulting program has the exact same semantics with or without it. But surfacing optimizer decisions gives more opportunity to break the program in surprising ways.

literal_pow is a great comparison, but it's also a very ugly and special purpose hack...

@dlfivefifty
Copy link
Member Author

I'm not a compiler designer but it would be convenient if all functions behaved like literal_pow: I have a special type that I want to overload 1 .- x to return a different type then y = 1; y .- x... but that's probably a discussion for somewhere else.

What about supporting @SVector a[3:end]?

@c42f
Copy link
Member

c42f commented Sep 25, 2020

a special type that I want to overload 1 .- x to return a different type then y = 1; y .- x

Well this does break referential transparency everywhere that literals appear. This is also why literal_pow is kinda bad (if oh-so-handy).

@dlfivefifty
Copy link
Member Author

I would argue that literal constants could have been implemented as a special type, essentially how literal_pow works with RefValue or how π works , which then would not have broken referential transparency. Though dealing with assignment x = 5 would be a bit tricky ( ie would it require x = Int(5) ?).

Anyways at this point it's too late and that's a bit of an off topic discussion...

@c42f
Copy link
Member

c42f commented Sep 26, 2020

I guess assignment already breaks referential transparency by introducing sequence points... so in a sense that's the place to degrade "literal types" into normal numbers. But yeah, probably pure speculation at this point :)

Having a[3:end] work is pretty tempting. The counter argument is that it makes generic-looking code like the following a lot worse

for i=1:length(a)
    b[i] = foo(a[i:end])
end

but maybe that's ok?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arrays AbstractArray interface and array operations feature features and feature requests
Projects
None yet
Development

No branches or pull requests

4 participants