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

Expand and reframe discussion of optionals #143

Merged
merged 21 commits into from
Aug 30, 2023

Conversation

amartini51
Copy link
Member

@amartini51 amartini51 commented Jun 15, 2023

  • Reframe the discussion of optional unwrapping to not conceptually rely on force unwrapping.
  • Highlight the value of non-optional types never being nil, and how you can't forget to handle nil on an optional.
  • Explicitly list the ways you can handle a nil value, and briefly introduce the ?? operator.
  • Explain when you should consider using force unwrapping.
  • Reduce the comparison to C and Objective-C.
  • Fix some mis-use of note boxes, where they were highlighting information instead of asides that readers can choose to skip.

Fixes: rdar://41014749

Forum (post-hoc) pitch: https://forums.swift.org/t/65744

Made the merge by copying the contents of a Git working copy at 'main'
over to this working copy, replacing what was on this branch.  Confirmed
both 'main' and this branch have the same content by comparing the Git
tree that the commits point to:

    % git cat-file -p HEAD | grep tree
    tree c86b6dd88a6ff5df836cdf53124e213c8f0f0009

    % git cat-file -p main | grep tree
    tree c86b6dd88a6ff5df836cdf53124e213c8f0f0009
Generated a patch of this branch's changes using git-diff.  Manually
re-applied those changes to the markdown file.  Confirmed that the
branch still makes the same changes by comparing the diffs:

    opendiff \
    =(git diff --patience --word-diff=porcelain main...optional_41014749_RST) \
    =(git diff --patience --word-diff=porcelain optional_41014749^-)
@amartini51 amartini51 marked this pull request as ready for review June 21, 2023 22:38
amartini51 and others added 3 commits June 27, 2023 10:14
Co-authored-by: Xiaodi Wu <13952+xwu@users.noreply.github.com>
Code like the following is an anti-pattern -- Swift has better idioms
for working with optionals:

    if x != nil { doSomething(x!) }

The only reason to compare == or != nil is for flow control -- so moved
the information there.
Copy link
Contributor

@chuckdude chuckdude left a comment

Choose a reason for hiding this comment

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

Please see edits and comments within.

To write an optional type,
you write a question mark (`?`)
after the name of the type that the optional contains ---
for example, the type of an optional `Int` is `Int?`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
for example, the type of an optional `Int` is `Int?`.
for example, `Int?`.

for example, the type of an optional `Int` is `Int?`.
An optional `Int` always contains
either some `Int` value or no value at all.
It can't contain anything else, like a `Bool` value or a `String` value.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
It can't contain anything else, like a `Bool` value or a `String` value.
It can't contain anything else, like a `Bool` or `String` value.

> If a constant or variable in your code needs to work with
> the absence of a value under certain conditions,
> always declare it as an optional value of the appropriate type.

If you define an optional variable without providing a default value,
the variable is automatically set to `nil` for you:
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
the variable is automatically set to `nil` for you:
the variable is automatically set to `nil`:

If a constant or variable in your code needs to work with
the absence of a value under certain conditions,
declare it as an optional value of the appropriate type.
A constant or variable that's declared as a non-optional value,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
A constant or variable that's declared as a non-optional value,
A constant or variable that's declared as a non-optional value

```
This separation of optional and non-optional values
lets you explicitly mark what information can be missing,
and makes it easier to write correct code that handle missing values.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
and makes it easier to write correct code that handle missing values.
and makes it easier to write code that handles missing values.


For more information about enforcing data requirements
and checking assumptions at runtime,
see <doc:TheBasics#Assertions-and-Preconditions> below.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
see <doc:TheBasics#Assertions-and-Preconditions> below.
see <doc:TheBasics#Assertions-and-Preconditions>.

@@ -1570,6 +1623,11 @@ and can definitely be assumed to exist at every point thereafter.
The primary use of implicitly unwrapped optionals in Swift is during class initialization,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
The primary use of implicitly unwrapped optionals in Swift is during class initialization,
Use implicitly unwrapped optionals in Swift when initializing a class,

Comment on lines 1900 to 1904
Trying to recover from an invalid state isn't possible ---
because the assertion failed,
you know that at least one piece of the program's data is invalid,
but you don't know why it's invalid
or what additional state is also invalid.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Trying to recover from an invalid state isn't possible ---
because the assertion failed,
you know that at least one piece of the program's data is invalid,
but you don't know why it's invalid
or what additional state is also invalid.
Recovering from an invalid state is impossible.
When an assertion fails,
at least one piece of the program's data is invalid ---
but you don't know why it's invalid
or whether an additional state is also invalid.

> Optionals of *any* type can be set to `nil`, not just object types.

### If Statements and Forced Unwrapping

You can use an `if` statement to find out whether an optional contains a value
by comparing the optional against `nil`.
You perform this comparison with the “equal to” operator (`==`)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
You perform this comparison with the equal to” operator (`==`)
You perform this comparison with the equal-to operator (`==`)

@@ -1308,6 +1280,9 @@ or the “not equal to” operator (`!=`).
If an optional has a value, it's considered to be “not equal to” `nil`:
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
If an optional has a value, it's considered to be “not equal to” `nil`:
If an optional has a value, it's considered as not-equal-to, `nil`:

Fixes: rdar://111129109

Co-authored-by: Chuck Toporek <chuck_toporek@apple.com>
@amartini51
Copy link
Member Author

amartini51 commented Aug 21, 2023 via email

Copy link
Contributor

@chuckdude chuckdude left a comment

Choose a reason for hiding this comment

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

Approved with changes as noted in Alex's latest commit:

f990214

Thank you for the detailed response. :)

@amartini51 amartini51 merged commit 82623c9 into swiftlang:main Aug 30, 2023
@amartini51 amartini51 deleted the optional_41014749 branch August 30, 2023 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants