diff --git a/NEWS.md b/NEWS.md index 38bb0df50134e..4bc1c5c37c8ec 100644 --- a/NEWS.md +++ b/NEWS.md @@ -44,9 +44,6 @@ New language features * Values for `Enum`s can now be specified inside of a `begin` block when using the `@enum` macro ([#25424]). - * `a[begin]` can now be used to address the first element of an integer-indexed collection `a`. - The index is computed by `firstindex(a)` ([#23554]). - Language changes ---------------- diff --git a/doc/src/manual/functions.md b/doc/src/manual/functions.md index 0664f6f758f98..fc3aaa87dd938 100644 --- a/doc/src/manual/functions.md +++ b/doc/src/manual/functions.md @@ -692,8 +692,8 @@ the results (see [Pre-allocating outputs](@ref)). A convenient syntax for this i is equivalent to `broadcast!(identity, X, ...)` except that, as above, the `broadcast!` loop is fused with any nested "dot" calls. For example, `X .= sin.(Y)` is equivalent to `broadcast!(sin, X, Y)`, overwriting `X` with `sin.(Y)` in-place. If the left-hand side is an array-indexing expression, -e.g. `X[begin+1:end] .= sin.(Y)`, then it translates to `broadcast!` on a `view`, e.g. -`broadcast!(sin, view(X, firstindex(X)+1:lastindex(X)), Y)`, +e.g. `X[2:end] .= sin.(Y)`, then it translates to `broadcast!` on a `view`, e.g. +`broadcast!(sin, view(X, 2:lastindex(X)), Y)`, so that the left-hand side is updated in-place. Since adding dots to many operations and function calls in an expression diff --git a/doc/src/manual/interfaces.md b/doc/src/manual/interfaces.md index 3e19bbf93357c..1ca83709c9587 100644 --- a/doc/src/manual/interfaces.md +++ b/doc/src/manual/interfaces.md @@ -161,8 +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 | -| `firstindex(X)` | The first index, used in `X[begin]` | -| `lastindex(X)` | The last index, used in `X[end]` | +| `firstindex(X)` | The first index | +| `lastindex(X)` | The last index, used in `X[end]` | For the `Squares` iterable above, we can easily compute the `i`th element of the sequence by squaring it. We can expose this as an indexing expression `S[i]`. To opt into this behavior, `Squares` @@ -178,9 +178,8 @@ julia> Squares(100)[23] 529 ``` -Additionally, to support the syntax `S[begin]` and `S[end]`, we must define [`firstindex`](@ref) and -[`lastindex`](@ref) to specify the first and last valid -index, respectively: +Additionally, to support the syntax `S[end]`, we must define [`lastindex`](@ref) to specify the last +valid index. It is recommended to also define [`firstindex`](@ref) to specify the first valid index: ```jldoctest squaretype julia> Base.firstindex(S::Squares) = 1 diff --git a/doc/src/manual/strings.md b/doc/src/manual/strings.md index 1f0339864fe3d..2f680f7b4b41f 100644 --- a/doc/src/manual/strings.md +++ b/doc/src/manual/strings.md @@ -168,9 +168,6 @@ julia> """Contains "quote" characters""" If you want to extract a character from a string, you index into it: ```jldoctest helloworldstring -julia> str[begin] -'H': ASCII/Unicode U+0048 (category Lu: Letter, uppercase) - julia> str[1] 'H': ASCII/Unicode U+0048 (category Lu: Letter, uppercase) @@ -183,8 +180,8 @@ julia> str[end] Many Julia objects, including strings, can be indexed with integers. The index of the first element is returned by [`firstindex(str)`](@ref), and the index of the last element -with [`lastindex(str)`](@ref). The keywords `begin` and `end` can be used inside an indexing -operation as shorthand for the first and last index along the given dimension. +with [`lastindex(str)`](@ref). The keyword`end` can be used inside an indexing +operation as shorthand for the last index along the given dimension. Most indexing in Julia is 1-based: the first element of many integer-indexed objects is found at index 1. (As we will see below, this does not necessarily mean that the last element is found at index `n`, where `n` is the length of the string.) @@ -203,7 +200,7 @@ julia> str[end÷2] Using an index less than 1 or greater than `end` raises an error: ```jldoctest helloworldstring -julia> str[begin-1] +julia> str[0] ERROR: BoundsError: attempt to access "Hello, world.\n" at index [0] [...] diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 86890b5557364..aef2a8485da17 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -86,11 +86,11 @@ (define (expand-compare-chain e) (car (expand-vector-compare e))) -;; return the appropriate computation for a `begin` or `end` symbol for indexing +;; return the appropriate computation for an `end` symbol for indexing ;; the array `a` in the `n`th index. ;; `tuples` are a list of the splatted arguments that precede index `n` ;; `last` = is this last index? -;; returns a call to, e.g., lastindex(a) or last(axes(a,n)) +;; returns a call to lastindex(a) or last(axes(a,n)) (define (end-val a n tuples last) (if (null? tuples) (if (and last (= n 1)) @@ -101,31 +101,20 @@ tuples)))) `(call (top last) (call (top axes) ,a ,dimno))))) -(define (begin-val a n tuples last) - (if (null? tuples) - (if (and last (= n 1)) - `(call (top firstindex) ,a) - `(call (top first) (call (top axes) ,a ,n))) - (let ((dimno `(call (top +) ,(- n (length tuples)) - ,.(map (lambda (t) `(call (top length) ,t)) - tuples)))) - `(call (top first) (call (top axes) ,a ,dimno))))) - -;; replace `begin` and `end` for the closest ref expression, so doesn't go inside nested refs -(define (replace-beginend ex a n tuples last) +;; replace `end` for the closest ref expression, so doesn't go inside nested refs +(define (replace-end ex a n tuples last) (cond ((eq? ex 'end) (end-val a n tuples last)) - ((eq? ex 'begin) (begin-val a n tuples last)) ((or (atom? ex) (quoted? ex)) ex) ((eq? (car ex) 'ref) ;; inside ref only replace within the first argument - (list* 'ref (replace-beginend (cadr ex) a n tuples last) + (list* 'ref (replace-end (cadr ex) a n tuples last) (cddr ex))) (else (cons (car ex) - (map (lambda (x) (replace-beginend x a n tuples last)) + (map (lambda (x) (replace-end x a n tuples last)) (cdr ex)))))) -;; go through indices and replace the `begin` or `end` symbol +;; go through indices and replace the `end` symbol ;; a = array being indexed, i = list of indices ;; returns (values index-list stmts) where stmts are statements that need ;; to execute first. @@ -144,17 +133,17 @@ (loop (cdr lst) (+ n 1) stmts (cons (cadr idx) tuples) - (cons `(... ,(replace-beginend (cadr idx) a n tuples last)) + (cons `(... ,(replace-end (cadr idx) a n tuples last)) ret)) (let ((g (make-ssavalue))) (loop (cdr lst) (+ n 1) - (cons `(= ,g ,(replace-beginend (cadr idx) a n tuples last)) + (cons `(= ,g ,(replace-end (cadr idx) a n tuples last)) stmts) (cons g tuples) (cons `(... ,g) ret)))) (loop (cdr lst) (+ n 1) stmts tuples - (cons (replace-beginend idx a n tuples last) ret))))))) + (cons (replace-end idx a n tuples last) ret))))))) ;; GF method does not need to keep decl expressions on lambda args ;; except for rest arg @@ -1511,8 +1500,7 @@ (idxs (cddr e))) (let* ((reuse (and (pair? a) (contains (lambda (x) - (or (eq? x 'begin) - (eq? x 'end) + (or (eq? x 'end) (eq? x ':) (and (pair? x) (eq? (car x) ':)))) @@ -1527,7 +1515,7 @@ (define (expand-update-operator op op= lhs rhs . declT) (cond ((and (pair? lhs) (eq? (car lhs) 'ref)) - ;; expand indexing inside op= first, to remove "begin", "end", and ":" + ;; expand indexing inside op= first, to remove "end" and ":" (let* ((ex (partially-expand-ref lhs)) (stmts (butlast (cdr ex))) (refex (last (cdr ex)))