We've discussed four possibile conventions for the case of initialisms. This document examines the tradeoffs.
If the initialism starts a non-type name, downcase it; otherwise, upcase it.
This is existing practice in the Swift standard library.
let asciiPlus = "+".utf8.first!
let titleHasMultipleWords = title.utf16.contains(asciiSpace)
let hasURL = page.webAddress != nil
let heading = "<h1>\(title.htmlEncode(asciiOnly: true))</h1>"
let urlForPublication = URL("http://forkjoin.net/\(fork)/knife/spoon")
document.urlForPublication = urlForPublication
if let validated = HTMLValidator(page.webAddress).validHTML {
post(XMLRPCRequest(.validated))
}
- Initialisms in public APIs appear as in ordinary text.
- All initialisms in code appear as in ordinary text.
- Makes word boundaries obvious.
- [⅓] Encourages “spelling” rather than “pronouncing” the initialism.
- Minimizes possibility of name collision
- Can distinguish type names from others on sight.
Treat whole the initialism like an ordinary word
This was suggested by Charles Kissinger on swift-evolution and then echoed by Trent Nadeau. It is also existing practice in .NET.
let asciiPlus = "+".utf8.first!
let titleHasMultipleWords = title.utf16.contains(asciiSpace)
let hasUrl = page.webAddress != nil
let heading = "<h1>\(title.htmlEncode(asciiOnly: true))</h1>"
let urlForPublication = Url("http://forkjoin.net/\(fork)/knife/spoon")
document.urlForPublication = urlForPublication
if let validated = HtmlValidator(page.webAddress).validHtml {
post(XmlRpcRequest(.validated))
}
- Initialisms in public APIs appear as in ordinary text.
- All initialisms in code appear as in ordinary text.
- Makes word boundaries obvious.
- Encourages “spelling” rather than “pronouncing” the initialism.
- Minimizes possibility of name collision
- Can distinguish type names from others on sight.
If the initialism starts a local variable name, downcase it; otherwise, upcase it
IIUC, this is existing practice in Cocoa.
For example,
let asciiPlus = "+".UTF8.first!
let titleHasMultipleWords = title.UTF16.contains(ASCIISpace)
let hasURL = page.webAddress != nil
let heading = "<h1>\(title.HTMLEncode(ASCIIOnly: true))</h1>"
let urlForPublication = URL("http://forkjoin.net/\(fork)/knife/spoon")
document.URLForPublication = urlForPublication
if let validated = HTMLValidator(page.webAddress).validHTML {
post(XMLRPCRequest(.validated))
}
- Initialisms in public APIs appear as in ordinary text.
- All initialisms in code appear as in ordinary text.
- Makes word boundaries obvious.
- [⅔] Encourages “spelling” rather than “pronouncing” the initialism.
- Minimizes possibility of name collision.
- Can distinguish type names from others on sight.
All initialisms are upcased, no exceptions.
For example,
let plusInASCII = “+”.UTF8.first!
let titleHasMultipleWords = title.UTF16.contains(spaceInASCII)
let hasURL = page.webAddress != nil
let heading = “<h1>\(title.encodeHTML(onlyASCII: true))</h1>” // Alternative label: restrictToASCII
let publicationURL = URL(“http://forkjoin.net/\(fork)/knife/spoon”)
document.publicationURL = publicationURL
if let validated = HTMLValidator(page.webAddress).validHTML {
post(XMLRPCRequest(.validated))
}
- Initialisms in public APIs appear as in ordinary text.
- All initialisms in code appear as in ordinary text.
- [½] Makes word boundaries obvious.
- Encourages “spelling” rather than “pronouncing” the initialism.
- [½] Minimizes possibility of name collision.
- [½] Can distinguish type names from others on sight.
Under convention #1 you can easily tell by looking at a name whether
it denotes a type. Whether or not that ability is valuable can of
course be debated: it's possible that our case convention's only value
is in reducing name collisions. In this convention, it's possible to
misread url
as “earl”, but at least URL
will not be misread.
Convention #2 preserves most of the benefits of convention #1, and
avoids the problem of word boundaries inherent in names like
XMLRPC
, XSLTiBook
(is that “XSLT iBook” or “XSL TiBook”?) and
LAPBACK
(“LAPB” + “ACK”). It's also simple: arguably, no special
rules are required for initialisms at all under this convention.
However, what it really means to UpperCamelCase or lowerCamelCase an
initialism is open to wide interpretation, so we'd probably need to
say something explicit anyway. Under this convention it's possible to
misread both url
and Url
as “earl.”
Under convention #3, the word boundary problem is back, and you can no longer tell by looking at a name that it denotes a type. The case conventions still serve to minimize collisions between types and everything else in most cases—but when a name starts with an initialism, that benefit is lost. Like the other conventions, it does not achieve consistency among all uses of a given initialism, because the standard practice (and one that is encouraged by our documentation, sample code, and WWDC presentations) is to use lower-case for initialisms at the beginning of parameter and local variable names:
func saveToURL(
_ url: NSURL,
// ^^^
forSaveOperation saveOperation: UIDocumentSaveOperation,
completionHandler completionHandler: ((Bool) -> Void)?)
Convention #4 is essentially the same as #3, without the exception for local
variables. It therefore has the same drawbacks. Just the same, these drawbacks
can be minimized by sticking to names that put initialisms at the end of the
name wherever possible and sensible, e.g. publicationURL
instead of
urlForPublication
. This is not so much a problem for names of methods and
properties because those often appear after a period at call site, e.g.
title.UTF16
. One notable benefit of this convention is that it does not
require any special rules or exceptions for initialisms.