Did Swift drop the underscore-prefix convention for instance variables, e.g., _window? If so, why?
7 Answers
Apple still uses _ in its Xcode boilerplate code as a convention for a non-public variable. You'll see a pattern like such:
class Foo { var _bar : Bar? = nil var bar : Bar { if _bar == nil { /* compute some stuff */ _bar = Bar (/* ... */) } return _bar! } } where access to the property is meant to be through the bar computed property. You find this in Apple CoreData templates.
2 Comments
In Objective-C when you declare a property @synthesize would create the getter and setters for you automatically since clang 3.2. So, the default @synthesize for a property foo would look like this:
@synthesize foo = _foo because of that _foo would then be the iVar. In other words you could have done the @synthesize yourself and called the iVar whatever you liked:
@synthesize foo = myiVarFoo so in this case there is no "_"
So now in Swift from the documentation:
Swift unifies these concepts into a single property declaration. A Swift property does not have a corresponding instance variable, and the backing store for a property is not accessed directly.
So from the documentation it's clear that swift does not have a corresponding instance variable thus no need to have the "_" around anymore.
Comments
The underscore prefix was meant not to confuse the instance variable _foo with its getter foo.
In swift there's not such distinction between ivars and getters. Instead you only have properties, making the _ convention non necessary.
1 Comment
The answer is no because there are no "instance variables" right now in Swift. Only properties (stored properties and computed properties).
1 Comment
I'd say this _underscoreName convention is dropped (although some Apple templates still have it).
Swift's "Lazy Stored Properties" make _these unnecessary. This post:
http://mikebuss.com/2014/06/22/lazy-initialization-swift/
explains it well.
Comments
I use a leading underscore to denote a private symbol.
Yes, the underscores do hamper readability at first, but there is a valuable payoff in comprehension and maintainability.
e.g.:
final class SomeClass { fileprivate let _kMagicNumber: CGFloat = 3.14 fileprivate struct _PrivateInfo { let foo: Int let bar: String } fileprivate var _privateInfo: _PrivateInfo fileprivate func _setup(with info: _PrivateInfo) { ... } } etc.
At a glance, you can see which elements belong where.
You don't need to option-click or do the "who does this belong to?" dance.
Code comprehension shouldn't rely on an IDE's features. And there are times (GitHub, raw text files) where an IDE isn't available.
I understand the "it's not convention" argument. But conventions aren't written on stone tablets. Swift is rapidly evolving, as is our usage of it.
If the Swift team were to produce an annotation syntax for private symbols tomorrow, I'd use it. But until then...
Since I've got my soapbox out, please prefix your extensions.
Consider this snippet:
let color = "#ff7733".hexColor Where does the "hexColor" come from? Your own code? The Swift standard library? Foundation? UKit? (Hah!) A CocoaPod? Who knows?
(Seasoned CocoaPods users will know that every second open-source library implements a "hexColor" property. With all the problems that entails.)
So, given a company or project name like "Double Secret Probation", consider using:
let color = "#ff7733".dsp_hexColor Finally, I strongly recommend the books "Writing Solid Code" and "Code Complete".
Comments
The convention of a prefixing private vars long preceeded that of ObjCs (weird) property synthesis concept. Clarity was the original reason for such a prefix, not differentiation though it was useful and common to expose a public getter without the underscore...for obvious reasons. IMO, ObjC prop synthesis just put a big fat monkey wrench in the works confusing the h*** out of everyone...
What if you wanted a private synthesized property? In order to underscore-prefix your private synthesized property, you'd need a double underscore backing var. Apple specifically warned against double underscores and this created confusion. Should we bother to use synth'ed properties internally or stick with the backing var (which still had an underscore and was clearly private)? Should we just stop differentiating between private and public vars? Why??
In practice people would use the synthesized version internal to a class as a kind of smart setter, if and only if they wanted the smarts – but that broke down the ideal of encapsulation – choosing whether to use the synth'ed setter required apriori knowledge of what happened behind the scenes.
Meanwhile, as pointed out above, apple's internal code still used the convention, sometimes for synthesized properties too IIRC. And they still do for swift properties! But not consistently...The biggest evidence your language design policy is confusing is when your own devs aren't using it consistently!
Clarity was the original motive and it worked well. I say:
BRING BACK THE UNDERSCORE!
...for private vars and methods :)
(P.S. Dart even has this as an actual language convention in lieu of a private keyword!)
countthere's no way to determine at a glance whether it's an instance variable or a local variable (that I'm aware of). And instance variables can be "out-scoped" by local variables! Argh. $5 says underscore notation will be back for Swift 3.