Skip to content
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

Rename endof->lastindex and introduce firstindex. Fixes #23354 #25458

Merged
merged 2 commits into from
Jan 26, 2018

Conversation

timholy
Copy link
Member

@timholy timholy commented Jan 8, 2018

While working on JuliaLang/Juleps#47 I noticed that we really should have beginindex (see #23354). This almost resolves that issue: I think I have all the tedious stuff done, but my lisp is laughable and character-twiddling was insufficient to fix the parsing of a[begin]. Would love some help. @stevengj? (Anyone who wishes, you are more than welcome to push directly to this branch, or do whatever you find most convenient.)

I defined specific beginindex methods for every type that defines what is now called endindex (formerly endof). Since beginindex is a new function, I also added a "deprecation" that returns 1 for any object, as a way of encouraging package authors to define it as needed. Hope this seems like a reasonable strategy.

`(call (top endof) ,a)
`(call (top size) ,a ,n))
`(call (top endindex) ,a)
`(call (top last) (call (top axes) ,a ,n)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this a lot, but could we incorporate this behavior into endindex, too? That way the parser only lowers end to endindex(A) or endindex(A, n) for the one- and n-arg cases, respectively.

@stevengj
Copy link
Member

stevengj commented Jan 8, 2018

Can we just keep endof and call it beginof?

@ararslan
Copy link
Member

ararslan commented Jan 8, 2018

or firstof?

@timholy
Copy link
Member Author

timholy commented Jan 8, 2018

Keeping it endof is of course an option, just not what appeared to be decided in #23354. I'm happy to go back to endof, though.

If we implement a[begin] I don't think it makes sense to call it firstof.

If someone gets to the parsing portion of this soon, great. If not, perhaps it would make sense to merge with beginof/beginindex and then implement a[begin] in 1.x.

@timholy
Copy link
Member Author

timholy commented Jan 8, 2018

Note that the only part of this that would have to be done for 1.0 is the rename, which is part of why I tackled this.

@GregPlowman
Copy link
Contributor

Here's a user's perspective:

Can we just keep endof and call it beginof?

I think beginindex and endindex more clearly conveys that an index rather than an element is returned.
I used to get confused between endof(collection) and last(collection)

or firstof?

I don't think it ties in as nicely with a[begin]
#23354 (comment)

@Sacha0
Copy link
Member

Sacha0 commented Jan 8, 2018

Echoing @GregPlowman, the index names seem more descriptive.

Though firstindex/lastindex are less consistent with begin/end than beginindex/endindex, firstindex/lastindex are more consistent with first/last than beginindex/endindex. firstindex/lastindex also seem more descriptive/intuitive IMHO. (beginindex/endindex suggest performing "begin" and "end" operations on an index, whatever that would mean, rather than getting the first and last indices of a collection).

Intuitiveness in direct use of firstindex/lastindex (and particularly alongside first/last) seems like a more meaningful consideration than consistency between begin/end and the forms those lower to. Best! (Apologies for stoking the bikeshed!)

@stevengj
Copy link
Member

stevengj commented Jan 9, 2018

One difficulty with parsing a[begin] is that some look ahead is required, since a[begin...end] is valid.

Maybe if begin is encountered in a ref expression, it should only be treated as an identifier if it is followed by an operator, comma, or ]?

@timholy
Copy link
Member Author

timholy commented Jan 9, 2018

Maybe also preceded? e.g. a[2*begin:end].

@mbauman
Copy link
Member

mbauman commented Jan 9, 2018

When I had thought about doing this in the past, I was thinking we could just deprecate begin … end blocks within indexing altogether. We could also just break it entirely if there's enough weight to enabling this syntax relative to the number of uses of x[begin … end].

I really don't think we should try to support both begin/end as indices and begin … end blocks at the same time.

@stevengj
Copy link
Member

stevengj commented Jan 9, 2018

@mbauman, yes, you are probably right. For example, a[begin +1; end] is currently valid syntax (equivalent to a[1]), but it means that we can't tell purely from the subsequent character whether begin is the start of a block or should be used as a variable.

@yurivish
Copy link
Contributor

yurivish commented Jan 9, 2018

What would happen if the interior of an indexing expression contains a macro call that expands to a begin/end block, and would cases like a[f(begin 1 + 1 end)] still be allowed?

It feels like a very reasonable thing to just disallow begin...end blocks from syntactically appearing in the surface code so long as all the other ways they could come up continue to work.

@mauro3
Copy link
Contributor

mauro3 commented Jan 9, 2018

Could we still rename begin ... end blocks? block ... end would be reasonable.

@KristofferC
Copy link
Member

block ... end is quite appealing. for begins a for loop, if begins an if statement, block begins a block. begin is pretty non-saying, begin what?

@stevengj
Copy link
Member

stevengj commented Jan 9, 2018

@yurivish, we are discussing the parser, which affects only surface syntax. Macro expansion happens later, and wouldn't be affected.

@StefanKarpinski
Copy link
Member

I rather like endof and beginof but I certainly hear (and agree) with what @GregPlowman is saying about endindex and beginindex being much more clearly evocative of what they mean.

block ... end is not bad at all, but I also think that disallowing begin ... end inside of indexing is a pretty sane thing to do. This is already a bit of a problem since you cannot use the index meaning of end inside of a begin ... end block inside of an indexing expression (reasonably enough).

@Keno
Copy link
Member

Keno commented Jan 9, 2018

I don't have much to add here at the moment, except to add that in #25261 I ran into a bunch of problems with code assuming that the iteration and indexing states where identical (e.g. using start/endof to bound indices and next instead of nextindex), so I'm happy to see this.

@stevengj
Copy link
Member

stevengj commented Jan 9, 2018

(The term begin here probably comes from Scheme's (begin ...) construct.) It seems quite annoying to rename a basic keyword of the language, and to introduce a new reserved word block, at this stage of the game.

@timholy
Copy link
Member Author

timholy commented Jan 9, 2018

I'm fine with any reasonable solution to the parsing issues.

@StefanKarpinski
Copy link
Member

I think the best approach is probably to disallow begin ... end blocks inside of indexing in 0.7 and then introduce a[begin] as an analogue to a[end] in 1.0. The names beginindex and endindex seem fine to me.

@JeffBezanson JeffBezanson added the deprecation This change introduces or involves a deprecation label Jan 17, 2018
@JeffBezanson
Copy link
Member

I do prefer the names beginindex and endindex to the current names. If this PR is changed just to do those renamings, I can add a deprecation for begin ... end inside indexing, and then we can add a[begin] safely in 1.0.

JeffBezanson added a commit that referenced this pull request Jan 17, 2018
JeffBezanson added a commit that referenced this pull request Jan 18, 2018
@Keno
Copy link
Member

Keno commented Jan 22, 2018

Needs a rebase. If the syntax part of this is controversial, maybe we can at least get the beginindex parts? I need to separate indexing state from iteration before we can merge #25261, so this would be a good thing to base that on.

@Keno
Copy link
Member

Keno commented Jan 22, 2018

Actually I'll just go ahead, rebase this, and take out the syntax parts (hope you don't mind).

@Keno Keno added this to the 1.0 milestone Jan 22, 2018
@Keno
Copy link
Member

Keno commented Jan 22, 2018

Rebased. I backed out the begin syntax as a separate commit, so whoever wants to take that up after 1.0 can just revert that change.

@@ -161,7 +161,8 @@ julia> collect(Iterators.reverse(Squares(10)))' # transposed to save space
|:-------------------- |:-------------------------------- |
| `getindex(X, i)` | `X[i]`, indexed element access |
| `setindex!(X, v, i)` | `X[i] = v`, indexed assignment |
| `endof(X)` | The last index, used in `X[end]` |
| `beginindex(X)` | The first index, used in `X[begin]` |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The syntax here is a holdover.

@gabrielgellner
Copy link
Contributor

I find beginindex is really hard to scan due to the internal inin this feels like an future api wart to me.

@StefanKarpinski
Copy link
Member

We could just call it begindex :trollface:

@fredrikekre
Copy link
Member

... and endex. begindex and endex seems like a nice couple 😄

@KristofferC
Copy link
Member

KristofferC commented Jan 23, 2018

begindex and endex seems like a nice couple

Too bad they are exes.

@Keno
Copy link
Member

Keno commented Jan 24, 2018

Rebased again. I'm planning to merge this one CI passes.

@StefanKarpinski
Copy link
Member

Since beginindex is indeed a horrific name and when we discussed this previously, everyone agreed that firstindex and lastindex were the clearest names semantically, let's go with those instead. It's not so terrible that a[end] calls lastindex and a[begin] calls firstindex. lastindex is a far clearer name than endof for example, which was fairly opaque.

@JeffBezanson
Copy link
Member

JeffBezanson commented Jan 24, 2018

I agree. It's not overly confusing for a[end] to call lastindex. After all, it's also not obvious that a[end] would correspond to endof or endindex, or that . would call broadcast, etc.

@Keno
Copy link
Member

Keno commented Jan 24, 2018

Rebased and renamed.

@ararslan ararslan changed the title RFH: Rename endof->endindex and introduce beginindex. Fixes #23354 Rename endof->lastindex and introduce firstindex. Fixes #23354 Jan 24, 2018
@ararslan
Copy link
Member

You might want to amend the commit message for the first commit here since what it describes is no longer quite what it does, since the names are different.

@Keno
Copy link
Member

Keno commented Jan 24, 2018

Done

NEWS.md Outdated
@@ -991,6 +991,8 @@ Deprecated or removed

* `Base.@gc_preserve` has been deprecated in favor of `GC.@preserve` ([#25616]).

* `endof(a)` has been renamed `endindex(a)` ([#23554]).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lastindex

@Keno Keno force-pushed the teh/beginindex branch 2 times, most recently from cb6fd0e to c6de074 Compare January 25, 2018 01:20
@Keno
Copy link
Member

Keno commented Jan 25, 2018

Some idiot merged something that conflicts with this. I'll rebase again, sigh. Planning to merge next time we're green on CI.

timholy and others added 2 commits January 25, 2018 18:00
It was decided to delay this syntax change until after 1.0, since it
is non-breaking. Once somebody wants to take this up again, they can
simply revert this commit.
@Keno
Copy link
Member

Keno commented Jan 25, 2018

People expressed concern about the phrasing, so for the record, it was me in #25733, I'm the idiot ;).

@Keno Keno merged commit 7d3991f into master Jan 26, 2018
@ararslan ararslan deleted the teh/beginindex branch January 26, 2018 19:01
@timholy
Copy link
Member Author

timholy commented Jan 31, 2018

Thanks for picking this up and pushing it over the line, @Keno; it's been a busy few weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deprecation This change introduces or involves a deprecation
Projects
None yet
Development

Successfully merging this pull request may close these issues.