SE-0217 - The "Unwrap or Die" operator

I agree with this. One of the things I love Swift for is its clear and intuitive syntax. In that context, I don't find wrappedValue !! “message” intuitive enough.

5 Likes

The RHS of !! can still be a function call that tees information to another destination before returning the string to trap on, if you want that behavior.

1 Like

I'm sorry that @davedelong feels that his motives were questioned.

Again, to re-emphasize, my meaning is the exact opposite. Some months earlier, when asked for feedback, I made a particular critique of the proposal as it was then written. The same issue persists to this day, and @beccadax asked whether this was an issue with the proposal or with the feature proposed. My response is that, on the basis of presuming that the authors are capable people who work diligently and give due consideration to feedback, the persistence of the issue reflects a problem with the feature proposed.

To be honest, I am quite upset that the response from @davedelong is to attack me for making the presumption that he and his co-authors gave due consideration to the feedback, on the grounds that making that presumption is demanding his "infinite time." To my mind, it is a presumption of good faith that we all have to make of proposal authors.

8 Likes

No. Not at all.

We want to keep the standard library trim and svelte.

If people want to use !! in their own code, they can easily define it themselves.

5 Likes

No, “we” do not. I want the standard library to be as full featured and rich as possible.

If I wanted a minimal language I’d use C.

2 Likes

Although you may disagree, the official statement about what "we" want is to keep the standard library small:

We believe that the Swift standard library should remain small and laser-focused on providing support for language primitives.

Indeed, at least in 2017, you yourself acknowledged that this was a goal of the standard library.

8 Likes

The amount of emotional involvement in this thread (on both sides) is indeed slightly puzzling.

If this doesn't make the cut, ?? + Never can always be hand-rolled and used instead (I for one am glad for this thread, because I didn't even realise that was a possibility). If this does get included, nobody is forced to use it. It's not like Swift would radically become a different language.

It also seems like different people have very different ways of dealing with errors in their code, which is fair, so the question is whether Swift should stay opinionated or allow for a wider range of expression in this regard.

4 Likes

This is a pretty classic non-apology, it turns the blame around on the other person for their feelings, and following it up with a tit-for-tat attack on the other person is not a good idea. You don't need to defend yourself or even apologize at all necessarily, please just be mindful of the fact of how invoking other people's motivations can be perceived, and keep the discussion focused on the proposal.

13 Likes

I am slightly -1 on this proposal. All the points I want to make have been done before. I'll just summarise that while I am sympathetic with the goal of the proposal, I am worried about a few points:

  • it doesn't allow for customisation (logging, etc..) like a ?? Never solution would
  • it is not entirely clear for beginners that the String is purely for diagnostics like fatalError would

The problem addressed is significant enough to warrant a change, but I still think this might not be the right solution.

Like said previously, I think it doesn't fit the customisation and clarity aspects of Swift.

Nope!

An in-depth reading of the different arguments.

3 Likes

@Joe_Groff, to be clear, I publicly apologized immediately and directly to @davedelong, and made it clear that causing offense was not my intention:

I then explained how my critique was directed at the ideas proposed and not at his or anyone else's motivations, and that I assumed only the best of intentions. Let me say again that I am very hurt by @davedelong's reply. I was accused of the following, which no fair reading of what I wrote could support:

This is not some sort of tit-for-tat ploy; I really am upset. I spent the better part of the morning crafting a detailed response to contribute to the discussion, trying to make my points as clearly as possible, and I have explained what I meant as clearly as I could.

3 Likes

I would say the question of "standard library trim" is largely irrelevant to the merits of this specific proposal. No matter what, the standard library is responsible for "providing support for language primitives" as @xwu pointed out, and since this proposal is pitched as becoming an idiomatic way of handling unexpected nils, going so far as propose changes to fixits to use the new operator, it's arguably vying to become one of those primitives. The role and scope of the standard library is an interesting question I think we have some work to do to clarify, but I don't think that discussion belongs in this review thread.

6 Likes

I'm in support of adding !! — and I generally err on the conservative side when it comes to growing the standard library. I can see places in my apps and frameworks where I would like to be able to annotate the force-unwraps with a more descriptive message. I know I am guilty of just writing value! in the past because I was too lazy to write out guard let x = optional else { fatalError("descriptive reason") }.

I think some of the proposal examples are spurious, like the let context = UIGraphicsGetCurrentContext() !! "drawRect context guarantee was breached" example is more appropriately handled by ! IMO, but this is probably subjective and I assume Swift documentation is not based off contributor proposal examples. As fix-its are pseudo-documentation in themselves, I would prefer that !! be added and not have the default fix-it changed from ! — at least make it the second option in the list of fix-it options. I worry that it would get it in the way, and generally annoy people who know what they are doing. Fix-its are not a source compatibility issue so being conservative here doesn't really have a downside.

I greatly prefer a specially denoted operator, !! , than the Never-bottom type idea of value ?? fatalError(...). That feels far too tricksy for me, and code that — to my eyes at least — looks fancy rather than obvious. And a point of pure elegance in favour, I like being able to use my eyes to scan with Ctrl-F ! and get a rough sense of where the 'trapdoors' in a piece of code are. !! supports that convenience further.

I was chewing over the lack of customisation concern brought up by others up-thread, but I was satisfied with @Ben_Cohen's response that a custom logging function could interoperate well with !! as-is, essentially acting as middleware and ultimately passing the error message as the return value to type-check with the operator.

2 Likes

This point keeps coming up on this thread and I'd like to address it. We offer !! Never as an alternate. It is wordier because of fatalError() but retains the right semantics (!! is the "or die" operator vs ?? as the "or fallback value" operator).

Would you (and others) change your vote if the Core Team went with !! Never over !! String?

3 Likes

Sorry, something I forgot to mention in my previous review:

Rather than being implemented with fatalError(), I believe !! should be implemented with preconditionFailure(). This would make it match the behavior of !, which cheats for speed in -Ounchecked but traps and prints a message in -O. That means it won't print the message in -Ounchecked, but if you're using that mode, you should be prepared to get exactly what you asked for whether you like it or not.

(I consider this to be correcting a minor mistake in the proposal, not proposing an alternative. I still support the expr !! "message" syntax over the alternative with an explicit call on the right side, and one reason I prefer it is because !! preconditionFailure("...") is longer and less obvious than !! fatalError("...") even though it's probably what you should be doing.

Also, another reason is that !! Never means you have to learn what the various functions which can go on the right side do and when you should use each one. That's bad for language learners, for much the same reason public static void main(String[] args) is bad for learners.)

I'd totally support this paragraph if [SR-905] precondition failure should show message in crash report - Swift did not exist: preconditions don't report any failure message in release builds. Yes nobody believes it but it's sadly true: you can't both use precondition and hope meaningful crash reports. I wish this bug would be fixed. Until then, we have to eat our fatalError soup. (cc @jrose: pleaaaaase)

I haven't reviewed this proposal yet but have been following the review thread closely. I have concluded that I think the String variant is a little too limited and cute / clever / cryptic, especially for the standard library. It also sacrifices accurate reporting of the file and line in which the error occurred which I think is a substantial problem that must be addressed by any version of this proposal that is accepted.

The Never option seems like more reasonable sugar that:

  1. is substantially more clear (IMO)
  2. correctly reports the file and line where the unwrap was attempted
  3. affords the flexibility of using assertionFailure, preconditionFailure and custom Never-returning functions

I do think !! is more appropriate than ?? even with the Never overload because a reader may not immediately know that a function returns Never (names are not always as good as they should be). !! would also play nicer than a new overload of ?? with generic placeholder functions overloaded on the return type (i.e. myOptional || TODO("provide a default value").

With the above in mind, I support the !! Never version while I oppose the !! String version.

5 Likes

Yes. value !! "message" as sugar for value ?? preconditionFailure("message") is a great example of progressive disclosure.

Edit: To say it in a different fashion: I don't think Never will ever enter a Swift crash-course. It is not realistic to force it down the throat of newcomers: they just won't swallow it.

For those who did not read the proposal: the main goal is to help newcomers deal with unexpected nils. During the first days of exposition to swift, not after several years of Swift programming.

Oof, that's pretty unfortunate. But I really don't see a good reason to treat !! differently from any other precondition—we ought to care about source location leaks and code size vs. error descriptiveness exactly as much for !! as for any other precondition.

You say it. We just can't use preconditions in production code.

Sure. But... I won't use !! if the string does not pop up in crash reports. And I will tell people to avoid it as well. I'd say that fixing SR-905 is mandatory for !! to be based on preconditionFailure. On the other side, this proposal can start with fatalError, and move to preconditionFailure afterwards. Anything is OK as long as !! plays its score: REPORT errors (regardless of code size).

3 Likes

I would if it could be “chained”.

?? allows

let result:String = some ?? some2 ?? some3 ?? ""

would this work?

let result:String = some ?? some2 ?? some3 !! fatalError("oops")
3 Likes
Terms of Service

Privacy Policy

Cookie Policy