Why are extensions used so heavily?

When I look at declarations in Xcode, of Section for example, I see a main declaration and a bunch of extensions. What is the advantage of that over just having them in the main declaration?

In a related question, when you want to have a special init, but you want to retain the default implicit init, you have to put the special init in an extension. Why is this better than simply not turning off the default init if you've included one with a different signature?

For context, I see extension as being a way to modify extent types when you want local changes, or when the original code isn't available to you. This thing of extending a thing in the same file is strange.

3 Likes

It's a commonly used practice to break types into smaller parts, usually a main declaration and extensions to provide various protocol conformances. For the initializers, those are added in extensions if you want to keep the synthesized member-wise initializer, as you lose it if you have an init in the main type declaration. That's just a limitation of the language, one which could be lifted if we add the ability to control the member-wise initializer synthesis.

5 Likes

The compiler removes the implicit init when you provide an explicit init in the main declaration on the assumption that the type has invariants which must be established by the explicit init that the implicit init would permit breaking, if it existed.

However, preserving the implicit init is convenient, so the compiler provides a way to have both the implicit init and explicit inits, which is to put all explicit inits in extensions.

1 Like

Hmm. Does breaking it apart like actually improve readability? IMHO it hurts, if reading through Apple's declarations is any indicator.

I like the idea of being able to control member synthesis.

I don’t think it helps readability much but it certainly helps organize code, which is helpful for overall understandability.

5 Likes

Yeah, I see that, but I question it. It means you have to have a magic actions.

Perhaps a "default" attribute to say that this is the one to use instead of the implicit? Does that make sense?

Tbf, with a zillion properties/members (looking at you, String), it's not gonna be super readable either way.

2 Likes

To me what you have just said is a contradiction. Readability is about understanding.

And I would disagree that it helps organize better than say, comments. In fact, I think it's much worse. You repeat the word extension and the name of the class n times so you can (if Apple is any indicator) add a single line.

1 Like

It's usually much more than that. You can group things together by files/folder, i.e., all Codable implementations are in this file. It'd be much harder to organize large project without extension. You'd be forced to put all that is about a type in the same place, same file.

3 Likes

Holy Beans. Yeah, that another tradition I'm not quite a fan of: comments before the declaration. It's not horrible, but I got used to Python docstrings, which make for a very clear context. A little bit harder in the case of synthetic header files, since we are lacking a body to demarcate the end, but...

Yeah, I could see that. Having all the Codables or whatever in one place could make for a really nice pattern recognition situation.

:+1: - but you better be careful with such opinions ;-)

Yeah, that's why I was trying to assume there was an explanation rather than declaring it bogus off the bat. If the generated interface files can collect declarations across a code base, that'd explain the seemingly absurd division. I like the idea of Aspect Programming like abilities, so I'll not complain about it. :)

I still don't care for the way default initializers are handled. Maybe when I'm feeling bold I'll write a proposal. Prolly someone will beat me to it...

On the default initializers side of things I think this is a semi-recent pitch Explicit Memberwise Initializers
Not sure if there's anything newer

1 Like

I think a lot of it comes down to style, but also, the bigger the code base, the more of these layers are necessary for it to work. Sort of like a very large organization needs layers and departments and forms, which is a lot to wade through and sometimes not helpful for getting simple things done. Unfortunately, it does have its place. In particular, the dividing of the code by protocols lets you quickly know where to find the protocol conformance and compare across types. It also helps isolate code when multiple people need to work on or review something.

They seem trendy in Swift despite the fact they existed also in Objective-C.

Swift Extensions are often times used in 3 ways (there are more):

  1. Retroactive Modeling
  2. Protocol Extensions
  3. For organization purposes, where grouping a set of methods together within the same file that declared that class. For example, grouping private methods in an extension, or an extension to implement each protocol that the class implements.

The use of swift extensions for with regards to point 3 above is very trendy right now and I feel strongly that it is incorrect and has drawbacks. A simple // MARK: achieves the “code organization” intention of using extensions.

Reasons to not use extensions for organizing code within the same file:

  • Unlike MARKs, they do not show up in the source editor summary dropdown in Xcode. (Screenshot: Dropbox - File Deleted)
  • Must scroll through the file to find all protocol conformances
  • Extensions obviously can’t override methods, hence this limits how these groups are composed
  • Can’t add properties to extensions, so grouping is somewhat false and not always fully contained as they may suggest
  • Take more space than MARKs and not as concise
  • Lead to longer compile times (I am finding a source for this)
  • Myth: Extensions don’t fully force protocol conformance to be in the scope of that extension
  • Myth: They do not give ability to implement protocol privately

Objective-c has categories offer ability to be named yet this pattern isn’t trendy there, suddenly its trendy in Swift.

5 Likes

Extensions are “trendy” in Swift because they’re trivial to add compared to categories in Objective-C.

Edit: Plus they’re far more useful as well, as retroactive conformance wasn’t really a thing in Obj-C.

1 Like

My remark is mostly about the in-file code organization trendiness. Other aspects of extensions are great.

1 Like

They do in my Xcode. I see an Orange Ex in the function popup.

1 Like

They do not show what protocol, if any, they implement.

1 Like