In any case, given that we're discussing a "safe subscript", we need a way
to differentiate the safe subscript from the unsafe subscript. The only two
ways to do that are to either add an argument label or change the argument
type, and IMHO the best alternate argument type is `Index?`, since it's
pretty light-weight, already part of the stdlib, and already familiar to
Swift developers.
Compiler and syntax issues aside, the real issue with using `Int?` as the
type is this: If you take `Int?` as a subscript type, then someone can say
`foos[nil]`. What are you going to do about that? It's obviously incorrect,
so you really ought to fail a precondition, but that means you've opened a
"safety" hole as bad as the original one, purely to get a nice syntax.
So, I think if you're going to do this, you need an argument label. The
question then is, what label should we use?
The most common choice is `safe`, but "safe" has a specific meaning in the
Swift compiler and standard library (i.e. memory safety), and we shouldn't
muddy that. Instead I'll nominate `checking`, which in context reads like:
if let foo = foos[checking: i] { … }
(But keep in mind that you shouldn't use the checking subscript in
`tableView(_:numberOfRowsInSection:)` or any of the other table view
delegate methods. Section and row indices should always be derived from the
count of the same array you're indexing, so it should never be possible to
receive an invalid section or row index in a table view delegate/data
source method. If that happens, the only possible cause is programmer
error, and the correct behavior when Swift code detects programmer error is
to fail a precondition and trap.
I'd actually say the #1 reason not to add this feature is that a lot of
developers don't seem to understand this, and they're likely to use the
feature to make their code try to continue in the face of programmer error
instead of trapping like it properly should. A program in an inconsistent
state is dangerous; best to stop it quickly before it does some damage.)
Since you already beat me to the rest of what I was typing about optionals
as the index, I'll +1 the sentiment in this last part :)
The need for checking subscripts should be *extremely rare*, which is why I
think most of the proposals in this area flounder.
An out-of-bound index is a *logic error* in the program. In most cases
(like the tableView example cited above), the indices you use elsewhere to
access elements of those arrays should already be guaranteed by other
invariants in your program. If they're not, and if you think you need to
use a checked subscript, then you're just putting some tape over the
problem instead of fixing a serious underlying bug.
Most of the time you're working with arrays, you should be using for-in
loops (where indexes don't matter) or the Collection index APIs (which will
guarantee that you're getting valid indexes without worrying about that
fact that they're numbers underneath).
It should be quite rare that you're accessing elements at arbitrary numeric
indexes within an array. I imagine most such cases come from user
input—either a number the user has entered, or them clicking on a
particular location on a view and then you translate that pixel location
into an array index and look something up that way. In those cases, you
should probably just do the bounds checking yourself.
My 2 cents: Giving users checked subscripts for arrays will do more harm
than good for novice programmers—they're going to do the wrong thing with
them.
···
On Thu, Apr 13, 2017 at 2:55 PM Brent Royal-Gordon via swift-evolution < swift-evolution@swift.org> wrote:
On Apr 13, 2017, at 9:18 AM, David Sweeris via swift-evolution < > swift-evolution@swift.org> wrote:
--
Brent Royal-Gordon
Architechies
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution