15

Did Swift drop the underscore-prefix convention for instance variables, e.g., _window? If so, why?

3
  • Are any of the below answers worthy of a 'answer'? Commented Sep 18, 2015 at 15:59
  • 1
    Sure, I selected one. Commented Sep 18, 2015 at 17:40
  • The thing that bothers me about this is that the swift property can seemingly be accessed with or without reference to self. So if you see a variable called count there'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. Commented Apr 10, 2016 at 14:09

7 Answers 7

24

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.

Sign up to request clarification or add additional context in comments.

2 Comments

That makes converting my old code much easier. Nice.
The underscore is used to opt out of explicitly naming a parameter. Given that the Swift compiler isn't exactly lenient, this is unlikely to be an oversight. Rather Apple intended - at least for the time being - that the underscore be valid variable name syntax .
17

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

9

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

there still exist scenarios where a private property - that ideally has the same name as a getter - could be useful. As stored properties cannot be overridden, it might be useful to have a superclass that provides a stub method, say foo(), that must be overridden by the subclass. The subclass method might just return _foo.
3

The answer is no because there are no "instance variables" right now in Swift. Only properties (stored properties and computed properties).

1 Comment

For all practical purposes we have instance variables, constants. And thus people need a practical naming system to denote private members.
3

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

2

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

0

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!)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.