removeFirst, optional equiviliant


(James Campbell) #1

If you call removeFirst and the array is empty it would be great if it was
optional so it could return nil or at least it threw an error so you could
handle that case.

···

--
 Wizard
james@supmenow.com
+44 7523 279 698


(Max Moiseev) #2

Hi James,

I believe this code <https://github.com/apple/swift/blob/master/stdlib/public/core/RangeReplaceableCollectionType.swift#L235> already handles empty array scenario by failing if the precondition is not met.
Or do you have something else in mind?

max

···

On Jan 6, 2016, at 9:36 AM, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

If you call removeFirst and the array is empty it would be great if it was optional so it could return nil or at least it threw an error so you could handle that case.

--
 Wizard
james@supmenow.com <mailto:james@supmenow.com>
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jordan Rose) #3

Hi, James. I'm having trouble thinking of when I want to remove something from an array unless the array is empty. The one case I can think of is when an array is being treated as a stack or queue and you're popping in a loop, but I (personally) rather write that with an explicit isEmpty check anyway. (It's not like it's any more or less efficient.)

Is there another scenario that I'm missing where this would be useful?

Thanks,
Jordan

···

On Jan 6, 2016, at 9:36, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

If you call removeFirst and the array is empty it would be great if it was optional so it could return nil or at least it threw an error so you could handle that case.

--
 Wizard
james@supmenow.com <mailto:james@supmenow.com>
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Dave Abrahams) #4

That method exists and is called popFirst

However, if you have an Array I suggest using popLast instead if you have the choice :slight_smile:

···

On Jan 6, 2016, at 9:36 AM, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

If you call removeFirst and the array is empty it would be great if it was optional so it could return nil or at least it threw an error so you could handle that case.

--
 Wizard
james@supmenow.com <mailto:james@supmenow.com>
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

-Dave


(Jacob Bandes-Storch) #5

Oops, I forgot this existed.

I'm assuming you're recommending popLast for performance reasons?
Unfortunately, for a queue, you'll need either insertAtIndex(0)/popLast or
append()/popLast (or a different data structure)...

Jacob

···

On Wed, Jan 6, 2016 at 3:41 PM, Dave Abrahams via swift-evolution < swift-evolution@swift.org> wrote:

That method exists and is called popFirst

However, if you have an Array I suggest using popLast instead if you have
the choice :slight_smile:

On Jan 6, 2016, at 9:36 AM, James Campbell via swift-evolution < > swift-evolution@swift.org> wrote:

If you call removeFirst and the array is empty it would be great if it was
optional so it could return nil or at least it threw an error so you could
handle that case.

--
 Wizard
james@supmenow.com
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Dave Abrahams) #6

Oops, I forgot this existed.

I'm assuming you're recommending popLast for performance reasons? Unfortunately, for a

…double-ended…

queue, you'll need either insertAtIndex(0)/popLast or append()/popLast (or a different data structure)…

Yes, the standard library should acquire a Deque data structure at some point.

Jacob

That method exists and is called popFirst

However, if you have an Array I suggest using popLast instead if you have the choice :slight_smile:

If you call removeFirst and the array is empty it would be great if it was optional so it could return nil or at least it threw an error so you could handle that case.

--
 Wizard
james@supmenow.com <mailto:james@supmenow.com>
+44 7523 279 698 <tel:%2B44%207523%20279%20698> _______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

-Dave

···

On Jan 6, 2016, at 3:42 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:
On Wed, Jan 6, 2016 at 3:41 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Jan 6, 2016, at 9:36 AM, James Campbell via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:


(Jacob Bandes-Storch) #7

Whoops, I meant append()/popFirst. That is, even for a single-ended queue,
you'll use one "first" operation (less efficient) and one "last" operation.

Oops, I forgot this existed.

I'm assuming you're recommending popLast for performance reasons?
Unfortunately, for a

…double-ended…

queue, you'll need either insertAtIndex(0)/popLast or append()/popLast (or
a different data structure)…

Yes, the standard library should acquire a Deque data structure at some
point.

Is there a SR for this?

···

On Wed, Jan 6, 2016 at 3:47 PM, Dave Abrahams <dabrahams@apple.com> wrote:

On Jan 6, 2016, at 3:42 PM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:

Jacob

On Wed, Jan 6, 2016 at 3:41 PM, Dave Abrahams via swift-evolution < > swift-evolution@swift.org> wrote:

That method exists and is called popFirst

However, if you have an Array I suggest using popLast instead if you have
the choice :slight_smile:

On Jan 6, 2016, at 9:36 AM, James Campbell via swift-evolution < >> swift-evolution@swift.org> wrote:

If you call removeFirst and the array is empty it would be great if it
was optional so it could return nil or at least it threw an error so you
could handle that case.

--
 Wizard
james@supmenow.com
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

-Dave


(Dave Abrahams) #8

Whoops, I meant append()/popFirst. That is, even for a single-ended queue, you'll use one "first" operation (less efficient) and one "last" operation.

No, a single-ended queue is a stack. You can use append and popLast on Array for that.

Oops, I forgot this existed.

I'm assuming you're recommending popLast for performance reasons? Unfortunately, for a

…double-ended…

queue, you'll need either insertAtIndex(0)/popLast or append()/popLast (or a different data structure)…

Yes, the standard library should acquire a Deque data structure at some point.

Is there a SR for this?

Not that I know of; have at it!

-Dave

···

On Jan 6, 2016, at 3:48 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:
On Wed, Jan 6, 2016 at 3:47 PM, Dave Abrahams <dabrahams@apple.com <mailto:dabrahams@apple.com>> wrote:

On Jan 6, 2016, at 3:42 PM, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:


(Lyle Parkyn) #9

1. What is your evaluation of the proposal?
I think the proposal has merit. It seeks to clarify a possible confusing issue.

I’m late to this issue, however, and perhaps because I read through everything in one go, but the keyword that came to me was “conformancetype”.
We’re talking protocols and protocols are about conformance - including the use a particular type within the protocol.

Although it looks longer “conformancetype” it is only one character more than “associatedtype"

2. Is the problem being addressed significant enough to warrant a change to Swift?
I agree the change is warranted.

3. Does this proposal fit well with the feel and direction of Swift?
I believe it does fit well with the feel and direction of the language.

4. If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
No.

5. How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
I studied the proposal and discussions.

6. Please state explicitly whether you believe that the proposal should be accepted into Swift.

I think proposal should be accepted.

- Lyle Parkyn


(James Campbell) #10

What I mean't is it would be great is if it was a native swift error :slight_smile: so
we could use try? syntax.

···

On Wed, Jan 6, 2016 at 6:32 PM, Max Moiseev <moiseev@apple.com> wrote:

Hi James,

I believe this code
<https://github.com/apple/swift/blob/master/stdlib/public/core/RangeReplaceableCollectionType.swift#L235> already
handles empty array scenario by failing if the precondition is not met.
Or do you have something else in mind?

max

On Jan 6, 2016, at 9:36 AM, James Campbell via swift-evolution < > swift-evolution@swift.org> wrote:

If you call removeFirst and the array is empty it would be great if it was
optional so it could return nil or at least it threw an error so you could
handle that case.

--
 Wizard
james@supmenow.com
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
 Wizard
james@supmenow.com
+44 7523 279 698


(James Campbell) #11

Yeah I was using this for a LIFO type system :slight_smile: glad to know there is a
method for this.

···

On Thu, Jan 7, 2016 at 12:09 AM, Dave Abrahams <dabrahams@apple.com> wrote:

On Jan 6, 2016, at 3:48 PM, Jacob Bandes-Storch <jtbandes@gmail.com> > wrote:

Whoops, I meant append()/popFirst. That is, even for a single-ended queue,
you'll use one "first" operation (less efficient) and one "last" operation.

No, a single-ended queue is a stack. You can use append and popLast on
Array for that.

On Wed, Jan 6, 2016 at 3:47 PM, Dave Abrahams <dabrahams@apple.com> wrote:

On Jan 6, 2016, at 3:42 PM, Jacob Bandes-Storch <jtbandes@gmail.com> >> wrote:

Oops, I forgot this existed.

I'm assuming you're recommending popLast for performance reasons?
Unfortunately, for a

…double-ended…

queue, you'll need either insertAtIndex(0)/popLast or append()/popLast
(or a different data structure)…

Yes, the standard library should acquire a Deque data structure at some
point.

Is there a SR for this?

Not that I know of; have at it!

-Dave

--
 Wizard
james@supmenow.com
+44 7523 279 698


(Max Moiseev) #12

Ahhh, right.

I believe the thinking here is that since this is an avoidable error, it should be handled in the client code with an `if !array.isEmpty { … }`), leaving errors to really exceptional and unexpected conditions.
Using optional here will serve the same purpose, IMHO, but instead of preventing the condition, one would have to react to the consequences later. Moreover the type will now be Optional<Element> and it would also be really tempting to write something like `array.removeFirst()!` and have the same trapping behavior.

Dave, Dmitri, please correct me if I’m wrong.

max

···

On Jan 6, 2016, at 10:34 AM, James Campbell <james@supmenow.com> wrote:

What I mean't is it would be great is if it was a native swift error :slight_smile: so we could use try? syntax.

On Wed, Jan 6, 2016 at 6:32 PM, Max Moiseev <moiseev@apple.com <mailto:moiseev@apple.com>> wrote:
Hi James,

I believe this code <https://github.com/apple/swift/blob/master/stdlib/public/core/RangeReplaceableCollectionType.swift#L235> already handles empty array scenario by failing if the precondition is not met.
Or do you have something else in mind?

max

On Jan 6, 2016, at 9:36 AM, James Campbell via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

If you call removeFirst and the array is empty it would be great if it was optional so it could return nil or at least it threw an error so you could handle that case.

--
 Wizard
james@supmenow.com <mailto:james@supmenow.com>
+44 7523 279 698 <tel:%2B44%207523%20279%20698> _______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

--
 Wizard
james@supmenow.com <mailto:james@supmenow.com>
+44 7523 279 698


(James Campbell) #13

I personally would love to have it as optional behaviour. Not sure when you
would ever need it to be non optional ?

···

On Wed, Jan 6, 2016 at 6:54 PM, Max Moiseev <moiseev@apple.com> wrote:

Ahhh, right.

I believe the thinking here is that since this is an avoidable error, it
should be handled in the client code with an `if !array.isEmpty { … }`),
leaving errors to really exceptional and unexpected conditions.
Using optional here will serve the same purpose, IMHO, but instead of
preventing the condition, one would have to react to the consequences
later. Moreover the type will now be Optional<Element> and it would also be
really tempting to write something like `array.removeFirst()!` and have the
same trapping behavior.

Dave, Dmitri, please correct me if I’m wrong.

max

On Jan 6, 2016, at 10:34 AM, James Campbell <james@supmenow.com> wrote:

What I mean't is it would be great is if it was a native swift error :slight_smile: so
we could use try? syntax.

On Wed, Jan 6, 2016 at 6:32 PM, Max Moiseev <moiseev@apple.com> wrote:

Hi James,

I believe this code
<https://github.com/apple/swift/blob/master/stdlib/public/core/RangeReplaceableCollectionType.swift#L235> already
handles empty array scenario by failing if the precondition is not met.
Or do you have something else in mind?

max

On Jan 6, 2016, at 9:36 AM, James Campbell via swift-evolution < >> swift-evolution@swift.org> wrote:

If you call removeFirst and the array is empty it would be great if it
was optional so it could return nil or at least it threw an error so you
could handle that case.

--
 Wizard
james@supmenow.com
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
 Wizard
james@supmenow.com
+44 7523 279 698

--
 Wizard
james@supmenow.com
+44 7523 279 698


(Rod Brown) #14

You wouldn't ever need for it to be non optional as it simply could be unwrapped with !

That said, there is a decent risk that developers might often get into a habit of forcibly unwrapping the value when the are removing items from arrays where they expect it to have content and it unexpectedly doesn't.

I think in regards to arrays, there is a decent history of user/dev responsibility to run those checks, and if you don't, there is an out of bounds exception. The check is simply your responsibility. This is designed to promote you to maintain awareness about how many items are in the array at all times, as mismanaged arrays are a cesspool of bugs. If we go through and put an optional here, wouldn't it make sense to make the return values of subscripting also optional? I think this is an all-or-nothing thing.

···

On 7 Jan 2016, at 6:12 AM, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

I personally would love to have it as optional behaviour. Not sure when you would ever need it to be non optional ?

On Wed, Jan 6, 2016 at 6:54 PM, Max Moiseev <moiseev@apple.com> wrote:
Ahhh, right.

I believe the thinking here is that since this is an avoidable error, it should be handled in the client code with an `if !array.isEmpty { … }`), leaving errors to really exceptional and unexpected conditions.
Using optional here will serve the same purpose, IMHO, but instead of preventing the condition, one would have to react to the consequences later. Moreover the type will now be Optional<Element> and it would also be really tempting to write something like `array.removeFirst()!` and have the same trapping behavior.

Dave, Dmitri, please correct me if I’m wrong.

max

On Jan 6, 2016, at 10:34 AM, James Campbell <james@supmenow.com> wrote:

What I mean't is it would be great is if it was a native swift error :slight_smile: so we could use try? syntax.

On Wed, Jan 6, 2016 at 6:32 PM, Max Moiseev <moiseev@apple.com> wrote:

Hi James,

I believe this code already handles empty array scenario by failing if the precondition is not met.
Or do you have something else in mind?

max

On Jan 6, 2016, at 9:36 AM, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

If you call removeFirst and the array is empty it would be great if it was optional so it could return nil or at least it threw an error so you could handle that case.

--
 Wizard
james@supmenow.com
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
 Wizard
james@supmenow.com
+44 7523 279 698

--
 Wizard
james@supmenow.com
+44 7523 279 698

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jacob Bandes-Storch) #15

You wouldn't ever *need* for it to be non optional as it simply could be
unwrapped with !

That said, there is a decent risk that developers might often get into a
habit of forcibly unwrapping the value when the are removing items from
arrays where they expect it to have content and it unexpectedly doesn't.

Isn't there exactly the same risk with removeFirst() as it exists today?
Arguably even riskier, because there's no "!" to warn you that it might
crash?

I think in regards to arrays, there is a decent history of user/dev
responsibility to run those checks, and if you don't, there is an out of
bounds exception. The check is simply your responsibility. This is designed
to promote you to maintain awareness about how many items are in the array
at all times, as mismanaged arrays are a cesspool of bugs. If we go through
and put an optional here, wouldn't it make sense to make the return values
of subscripting also optional? I think this is an all-or-nothing thing.

I personally would love to have it as optional behaviour. Not sure when
you would ever need it to be non optional ?

Ahhh, right.

I believe the thinking here is that since this is an avoidable error, it
should be handled in the client code with an `if !array.isEmpty { … }`),
leaving errors to really exceptional and unexpected conditions.
Using optional here will serve the same purpose, IMHO, but instead of
preventing the condition, one would have to react to the consequences
later. Moreover the type will now be Optional<Element> and it would also be
really tempting to write something like `array.removeFirst()!` and have the
same trapping behavior.

Dave, Dmitri, please correct me if I’m wrong.

max

What I mean't is it would be great is if it was a native swift error :slight_smile:
so we could use try? syntax.

Hi James,

I believe this code
<https://github.com/apple/swift/blob/master/stdlib/public/core/RangeReplaceableCollectionType.swift#L235> already
handles empty array scenario by failing if the precondition is not met.
Or do you have something else in mind?

max

If you call removeFirst and the array is empty it would be great if it
was optional so it could return nil or at least it threw an error so you
could handle that case.

--
 Wizard
james@supmenow.com
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
 Wizard
james@supmenow.com
+44 7523 279 698

--
 Wizard
james@supmenow.com
+44 7523 279 698

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Jacob

···

On Wed, Jan 6, 2016 at 1:15 PM, Rod Brown via swift-evolution < swift-evolution@swift.org> wrote:

On 7 Jan 2016, at 6:12 AM, James Campbell via swift-evolution < > swift-evolution@swift.org> wrote:
On Wed, Jan 6, 2016 at 6:54 PM, Max Moiseev <moiseev@apple.com> wrote:

On Jan 6, 2016, at 10:34 AM, James Campbell <james@supmenow.com> wrote:
On Wed, Jan 6, 2016 at 6:32 PM, Max Moiseev <moiseev@apple.com> wrote:

On Jan 6, 2016, at 9:36 AM, James Campbell via swift-evolution < >>> swift-evolution@swift.org> wrote:


(Rod Brown) #16

You make a fair point. I would agree the risk is far higher, to be honest. At least returning an optional forces you to do something about the fact it might not have happened, even if it's only to use the ! force unwrapper.

Also of note, as of OS X 10.7, removeLastObject for example on NSMutableArray no longer creates a range exception, and instead simply returns nil.

Perhaps we need to treat these methods as conveniences, and as such subscripting still gets range exceptions, but removeFirst, removeLast etc should get optional return types and no fail if it's empty?

···

On 7 Jan 2016, at 8:20 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

On Wed, Jan 6, 2016 at 1:15 PM, Rod Brown via swift-evolution <swift-evolution@swift.org> wrote:
You wouldn't ever need for it to be non optional as it simply could be unwrapped with !

That said, there is a decent risk that developers might often get into a habit of forcibly unwrapping the value when the are removing items from arrays where they expect it to have content and it unexpectedly doesn't.

Isn't there exactly the same risk with removeFirst() as it exists today? Arguably even riskier, because there's no "!" to warn you that it might crash?

I think in regards to arrays, there is a decent history of user/dev responsibility to run those checks, and if you don't, there is an out of bounds exception. The check is simply your responsibility. This is designed to promote you to maintain awareness about how many items are in the array at all times, as mismanaged arrays are a cesspool of bugs. If we go through and put an optional here, wouldn't it make sense to make the return values of subscripting also optional? I think this is an all-or-nothing thing.

On 7 Jan 2016, at 6:12 AM, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

I personally would love to have it as optional behaviour. Not sure when you would ever need it to be non optional ?

On Wed, Jan 6, 2016 at 6:54 PM, Max Moiseev <moiseev@apple.com> wrote:
Ahhh, right.

I believe the thinking here is that since this is an avoidable error, it should be handled in the client code with an `if !array.isEmpty { … }`), leaving errors to really exceptional and unexpected conditions.
Using optional here will serve the same purpose, IMHO, but instead of preventing the condition, one would have to react to the consequences later. Moreover the type will now be Optional<Element> and it would also be really tempting to write something like `array.removeFirst()!` and have the same trapping behavior.

Dave, Dmitri, please correct me if I’m wrong.

max

On Jan 6, 2016, at 10:34 AM, James Campbell <james@supmenow.com> wrote:

What I mean't is it would be great is if it was a native swift error :slight_smile: so we could use try? syntax.

On Wed, Jan 6, 2016 at 6:32 PM, Max Moiseev <moiseev@apple.com> wrote:

Hi James,

I believe this code already handles empty array scenario by failing if the precondition is not met.
Or do you have something else in mind?

max

On Jan 6, 2016, at 9:36 AM, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

If you call removeFirst and the array is empty it would be great if it was optional so it could return nil or at least it threw an error so you could handle that case.

--
 Wizard
james@supmenow.com
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
 Wizard
james@supmenow.com
+44 7523 279 698

--
 Wizard
james@supmenow.com
+44 7523 279 698

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Jacob


(Jacob Bandes-Storch) #17

I'd be in favor of that, although I imagine it would be very challenging to
change the nullability of the return type without wreaking havoc on
thousands of lines of legacy code. Having the migrator add "!" wouldn't be
all that great.

I think there's also precedent in the stdlib for there to be "unsafe"
variants of these things which skip the bounds-check if you really care for
performance reasons: like unsafeUnwrap(), you could have an
unsafeRemoveFirst().

Jacob Bandes-Storch

···

On Wed, Jan 6, 2016 at 1:30 PM, Rod Brown <rodney.brown6@icloud.com> wrote:

You make a fair point. I would agree the risk is far higher, to be honest.
At least returning an optional forces you to do something about the fact it
might not have happened, even if it's only to use the ! force unwrapper.

Also of note, as of OS X 10.7, removeLastObject for example on
NSMutableArray no longer creates a range exception, and instead simply
returns nil.

Perhaps we need to treat these methods as conveniences, and as such
subscripting still gets range exceptions, but removeFirst, removeLast etc
should get optional return types and no fail if it's empty?

On 7 Jan 2016, at 8:20 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

On Wed, Jan 6, 2016 at 1:15 PM, Rod Brown via swift-evolution < > swift-evolution@swift.org> wrote:

You wouldn't ever *need* for it to be non optional as it simply could be
unwrapped with !

That said, there is a decent risk that developers might often get into a
habit of forcibly unwrapping the value when the are removing items from
arrays where they expect it to have content and it unexpectedly doesn't.

Isn't there exactly the same risk with removeFirst() as it exists today?
Arguably even riskier, because there's no "!" to warn you that it might
crash?

I think in regards to arrays, there is a decent history of user/dev
responsibility to run those checks, and if you don't, there is an out of
bounds exception. The check is simply your responsibility. This is designed
to promote you to maintain awareness about how many items are in the array
at all times, as mismanaged arrays are a cesspool of bugs. If we go through
and put an optional here, wouldn't it make sense to make the return values
of subscripting also optional? I think this is an all-or-nothing thing.

On 7 Jan 2016, at 6:12 AM, James Campbell via swift-evolution < >> swift-evolution@swift.org> wrote:

I personally would love to have it as optional behaviour. Not sure when
you would ever need it to be non optional ?

On Wed, Jan 6, 2016 at 6:54 PM, Max Moiseev <moiseev@apple.com> wrote:

Ahhh, right.

I believe the thinking here is that since this is an avoidable error, it
should be handled in the client code with an `if !array.isEmpty { … }`),
leaving errors to really exceptional and unexpected conditions.
Using optional here will serve the same purpose, IMHO, but instead of
preventing the condition, one would have to react to the consequences
later. Moreover the type will now be Optional<Element> and it would also be
really tempting to write something like `array.removeFirst()!` and have the
same trapping behavior.

Dave, Dmitri, please correct me if I’m wrong.

max

On Jan 6, 2016, at 10:34 AM, James Campbell <james@supmenow.com> wrote:

What I mean't is it would be great is if it was a native swift error :slight_smile:
so we could use try? syntax.

On Wed, Jan 6, 2016 at 6:32 PM, Max Moiseev <moiseev@apple.com> wrote:

Hi James,

I believe this code
<https://github.com/apple/swift/blob/master/stdlib/public/core/RangeReplaceableCollectionType.swift#L235> already
handles empty array scenario by failing if the precondition is not met.
Or do you have something else in mind?

max

On Jan 6, 2016, at 9:36 AM, James Campbell via swift-evolution < >>>> swift-evolution@swift.org> wrote:

If you call removeFirst and the array is empty it would be great if it
was optional so it could return nil or at least it threw an error so you
could handle that case.

--
 Wizard
james@supmenow.com
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
 Wizard
james@supmenow.com
+44 7523 279 698

--
 Wizard
james@supmenow.com
+44 7523 279 698

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Jacob


(Rod Brown) #18

Having the migrator add a ! will result in consistent behaviour with current code.

The only issue here is that by adding in !, it somehow might suggest to someone reading the code "hey, the writer though about this and is sure it's safe" but really, they should have been checking it anyway currently, and at least someone can *see* their error...

- Rod

···

On 7 Jan 2016, at 8:33 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

I'd be in favor of that, although I imagine it would be very challenging to change the nullability of the return type without wreaking havoc on thousands of lines of legacy code. Having the migrator add "!" wouldn't be all that great.

I think there's also precedent in the stdlib for there to be "unsafe" variants of these things which skip the bounds-check if you really care for performance reasons: like unsafeUnwrap(), you could have an unsafeRemoveFirst().

Jacob Bandes-Storch

On Wed, Jan 6, 2016 at 1:30 PM, Rod Brown <rodney.brown6@icloud.com> wrote:
You make a fair point. I would agree the risk is far higher, to be honest. At least returning an optional forces you to do something about the fact it might not have happened, even if it's only to use the ! force unwrapper.

Also of note, as of OS X 10.7, removeLastObject for example on NSMutableArray no longer creates a range exception, and instead simply returns nil.

Perhaps we need to treat these methods as conveniences, and as such subscripting still gets range exceptions, but removeFirst, removeLast etc should get optional return types and no fail if it's empty?