Problem
There is an undocumented convention in Swift, of appending an underscore "_" to a public symbol or attribute in order to communicate some special meaning.
However, you will not find any mention of this practice within Swift's own documentation on swift.org, nor any explanation of the often subtle differences in meaning of "_". (Please correct me if I'm wrong. I did several searches and came up with nothing, and several read-throughs.)
Examples:
-
_enclosingInstance
(undocumented subscript method for property wrappers) -
_FormatSpecifiable
(protocol in SwiftUI) @_exported
@_functionBuilder
@_implementationOnly
@_transparent
@_silgen_name ("foo")
In each case, "_" means something slightly different, e.g. (my interpretations, correct me if I'm wrong):
- "Use of this symbol or attribute is unsupported by Apple."
- "This is part of a feature that has not gone fully through the Swift evolution process yet, and thus, no guarantees are made about how much it might change in the next release of Swift."
- "This feature is used internally for optimizability and resilience features of the Swift language, and is not intended for public use (unless you really know what you're doing)."
Proposed solution
We should canonicalize different ways to communicate these meanings in a clear way, rather than using the same symbol for each of these meanings.
Here are some examples of what could be more clear:
// Library author strongly suggests that you avoid subclassing or implementing.
š«FormatSpecifiable
// API is still under construction, subject to change.
@š§functionBuilder
// Special capability for internal Swift toolchain development.
@š ļøsilgen_name
This kind of convention would make it easy for people to add lint rules about which kinds of APIs and language features they're comfortable with allowing in their codebase. If I want to ban the use of undocumented APIs in Apple & third-party code, but I'm fine with using undocumented Swift features, I could ban -prepended symbols but allow
- and
-prepended ones in my lint rules.
Use of clear symbols would also make it obvious in a code-review when someone is using an undocumented feature.
The only substantial objection I could see to this would be that emojis can be a pain to type during code entry. However, this objection would be easy to solve via one or more of the following features added to your IDE:
- IDE performs a smart-replace between a typed underscore character, and the appropriate emoji, based on autocomplete.
- If you type _ after a space or on a new line, a contextual menu could appear that lets you select the appropriate symbol to prepend. (Considering that there would only need to be a handful of these, I don't see this as burdensome).
- Use text macros like this forum has:
:construction:
becomes
We could also add a new compiler flag to throw a warning or error if appears on any conformance declarations in your code, perhaps with the ability to set exceptions (to allow use of unsupported APIs from a specific library that's under development, while blocking the use of these from all other libraries).
Note:
If people are against the emoji idea, we should at least add proper documentation around the use of underscore so it's clear what it's supposed to mean in different contexts.