# Calling private methods from extensions in separate files

**URL:** <https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029>\
**Category:** Discussion\
**Created:** [December 13, 2021, 6:16pm UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029 "2021-12-13T18:16:25Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![tclementdev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tclementdev/32/13398_2.png) [@tclementdev](https://forums.swift.org/u/tclementdev)\
**Post date:** [December 13, 2021, 6:16pm UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/1 "2021-12-13T18:16:25Z")

</div>

I see that some developers really like to implement protocol conformances as extensions in separate files, but then Swift prevents access to private members that are declared in other files of the same type. The result is that developers will turn those members from private to internal which makes me quite sad. Is there a good reason that Swift isn't allowing access to private members when the extensions are declared in the same module?

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [December 13, 2021, 7:46pm UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/2 "2021-12-13T19:46:02Z")

</div>

Swift’s access modifiers are deliberately _lexical_, not _type-based_. The access modifier that allows use throughout a module is `internal`, within a file `fileprivate`, and within a _lexical_ scope `private`.

Other languages may offer type-based access modifiers, but that is deliberately not the case for Swift.

---

<div class="post-metadata">

**Author:** ![tclementdev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tclementdev/32/13398_2.png) [@tclementdev](https://forums.swift.org/u/tclementdev)\
**Post date:** [December 13, 2021, 8:00pm UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/3 "2021-12-13T20:00:36Z")

</div>

Well the point of my post is that I am arguing this is _bad_ because real-world codebase ends up using what is clearly the wrong access modifier, as those members become exposed to other types in the module once they become `internal`. Developers, as human beings, have a liking in tidying up things in their own places, this seems to have been overlooked.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [December 13, 2021, 8:07pm UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/4 "2021-12-13T20:07:25Z")

</div>

You asked a question about the rationale—I just replied with the answer. There’s been nothing overlooked in this area; you can read up on the extensive prior discussions by using the handy search function.

---

<div class="post-metadata">

**Author:** ![anon9791410](https://avatars.discourse-cdn.com/v4/letter/a/9fc348/32.png) [@anon9791410](https://forums.swift.org/u/anon9791410)\
**Post date:** [December 13, 2021, 8:12pm UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/5 "2021-12-13T20:12:12Z")

</div>

> [@tclementdev](#):
>
> Developers, as human beings, have a liking in tidying up things in their own places

You have apparently lived with some very different developers than I have. 🤢

---

<div class="post-metadata">

**Author:** ![tclementdev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tclementdev/32/13398_2.png) [@tclementdev](https://forums.swift.org/u/tclementdev)\
**Post date:** [December 13, 2021, 8:20pm UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/6 "2021-12-13T20:20:36Z")

</div>

I don't think it is uncommon, for example `swiftlint` has a [rule](https://realm.github.io/SwiftLint/file_length.html) enabled by default which complains when a file is over 400 lines. Developers end up splitting up files in extensions. Personally I think this is silly, but I can't stop developers from doing that, and I still haven't seen a good reason to prevent private access from extensions within the same module.

---

<div class="post-metadata">

**Author:** ![Tino](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tino/32/1073_2.png) [@Tino](https://forums.swift.org/u/Tino)\
**Post date:** [December 13, 2021, 9:27pm UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/7 "2021-12-13T21:27:17Z")

</div>

> [@xwu](#):
>
> Other languages may offer type-based access modifiers, but that is deliberately not the case for Swift.

I tend to disagree: `private` is already (partially) type-based access control, so the current system is not as clean as it used to be...

I don't think there should be yet another level, but it might be possible to improve the situation without a major change in the compiler:  
Not everything has to be enforced, and changing the behavior of tools with annotations could be enough. If autocompletion hides methods in certain contexts, and tooltips showed some warning, nothing else might be required (and such a system could be used for more situations — like methods which should never be called directly, but just overridden by subclasses...).

---

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [December 13, 2021, 9:49pm UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/8 "2021-12-13T21:49:38Z")

</div>

It's not clear to me that `internal` is a worse access modifier. If anything, I'd say that the addition of scoped `private` was a mistake, and the language was better when `private` meant what `fileprivate` means now.

---

<div class="post-metadata">

**Author:** ![tclementdev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tclementdev/32/13398_2.png) [@tclementdev](https://forums.swift.org/u/tclementdev)\
**Post date:** [December 13, 2021, 10:42pm UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/9 "2021-12-13T22:42:36Z")

</div>

hmm, `internal` does seem to be worse, members are now exposed to the whole module.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [December 13, 2021, 10:44pm UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/10 "2021-12-13T22:44:01Z")

</div>

> [@tclementdev](#):
>
> Is there a good reason that Swift isn't allowing access to private members when the extensions are declared in the same module?

I'm with you on this one, it feels wrong. IMHO type-based access modifiers would have been a better choice for swift. Unfortunately that ship has sailed.

---

<div class="post-metadata">

**Author:** ![QuinceyMorris](https://avatars.discourse-cdn.com/v4/letter/q/d26b3c/32.png) [@QuinceyMorris](https://forums.swift.org/u/QuinceyMorris)\
**Post date:** [December 13, 2021, 11:46pm UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/11 "2021-12-13T23:46:03Z")

</div>

> [@tclementdev](#):
>
> hmm, `internal` does seem to be worse, members are now exposed to the whole module.

There's a genuine problem with your alternative, though, which is that allowing extensions in other files to access `private` members is pretty much the same as changing `private` to `internal` _anyway_.

_Anyone_ can simply bypass your privacy restriction by implementing conformances to a made-up protocol, and thereby give effective access to everything that's supposed to be private.

At least one of the purposes of `private` is for a type implementation (in a single file) to be able to guarantee that there are no invisible dependencies on its private details from other ~~files~~ types in the same project. If you (the implementer or the type) are going to _trust_ everyone else (the clients of your type) that way, then your type may as well be `internal` instead of `private`.

I agree that there's a difficulty to be solved here. My preference would be for some kind of hierarchical sub-module system. Still, there's been a lot of discussion about solutions over the years, and no real convergence.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [December 14, 2021, 12:27am UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/12 "2021-12-14T00:27:46Z")

</div>

I think the alternative would be something like what other languages call `protected`: visible via limited interactions with the type. This could include subclasses, which is the typical usage, but could also include extensions in other files. So the property wouldn't be visible to consumers of the type, even internally, but would be to any subtype or extension. Personally, I would find this very useful to maximize the cleanliness of projects. Currently I'm forced to either allow things to be inappropriately visible internally or put everything in one file, including rather large subclasses.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [December 14, 2021, 1:18am UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/13 "2021-12-14T01:18:18Z")

</div>

> [@QuinceyMorris](#):
>
> There's a genuine problem with your alternative, though, which is that allowing extensions in other files to access `private` members is pretty much the same as changing `private` to `internal` _anyway_ .
> 
> _Anyone_ can simply bypass your privacy restriction by implementing conformances to a made-up protocol, and thereby give effective access to everything that's supposed to be private.
> 
> At least one of the purposes of `private` is for a type implementation (in a single file) to be able to guarantee that there are no invisible dependencies on its private details from other ~~files~~ types in the same project. If you (the implementer or the type) are going to _trust_ everyone else (the clients of your type) that way, then your type may as well be `internal` instead of `private` .

For this particular aspect the difference between `fileprivate` and `private` could have been used..

---

<div class="post-metadata">

**Author:** ![QuinceyMorris](https://avatars.discourse-cdn.com/v4/letter/q/d26b3c/32.png) [@QuinceyMorris](https://forums.swift.org/u/QuinceyMorris)\
**Post date:** [December 14, 2021, 1:36am UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/14 "2021-12-14T01:36:13Z")

</div>

I understand there are different approaches that different people might want to promote, but the key issue is that the only way for the implementer of a type to keep control of its private details (while spreading those details across multiple implementation files) is some scheme that _requires_ the implementer to _grant_ access to the additional files.

So, `protected` _could_ be problematic if anyone could subclass the base class in order get access to its private details.

I don't see exactly how `fileprivate` helps that much. Maybe something like `private("additionalFileName.swift")` could be a way of granting access.

This is basically a security issue.

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [December 14, 2021, 1:57am UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/15 "2021-12-14T01:57:24Z")

</div>

> [@QuinceyMorris](#):
>
> If you (the implementer or the type) are going to _trust_ everyone else (the clients of your type) that way, then your type may as well be `internal` instead of `private` .

Since the only way to access something that is `internal` is to be compiled into the same module (`@testable import` notwithstanding, and that requires that the module being imported opt-in to testable imports), why _wouldn't_ you trust those internal clients?

You mention "security issue" below, but if there's a major risk from declarations being too visible within the _same_ module, i.e. if a component can't trust the code given to the same compiler invocation, isn't that illustrative of a much more significant breakdown in the code review or build process? And if it really _is_ that sensitive, then maybe it _should_ be isolated in its own module?

The recurring desire to finely audit access control of the code within one's own module strikes me more as adversarial toward extremely uncommon hypothetical scenarios rather than serving a practical purpose for everyday Swift usage.

---

<div class="post-metadata">

**Author:** ![QuinceyMorris](https://avatars.discourse-cdn.com/v4/letter/q/d26b3c/32.png) [@QuinceyMorris](https://forums.swift.org/u/QuinceyMorris)\
**Post date:** [December 14, 2021, 2:38am UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/16 "2021-12-14T02:38:32Z")

</div>

> [@allevato](#):
>
> why _wouldn't_ you trust those internal clients?

It's not really about trust or security in the _security_ sense. It really does happen, though, that other people not familiar with the design of your class might add some kind of accessor to derive something from a private property, for example — and they get it wrong, or introduce a cross-type dependency you don't know about.

> [@allevato](#):
>
> And if it really _is_ that sensitive, then maybe it _should_ be isolated in its own module?

My feeling exactly. I'd love to have a _lightweight_ module system, such as hierarchical sub-modules defined within Swift itself, that provide boundaries around which inadvertent misuse of private details can be prevented.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [December 14, 2021, 2:57am UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/17 "2021-12-14T02:57:44Z")

</div>

IME, Swift's access control\* is such a delight to use that the old type-based system feels ancient no matter what languages I switched to. I can't quite put it into words, but Becca's word strongly resonate with me:

> [@Implement Alvarez & Monteiro's "typeprivate", possibly with one or two extra restrictions](https://forums.swift.org/t/implement-alvarez-monteiros-typeprivate-possibly-with-one-or-two-extra-restrictions/40994/13):
>
> It is the very arbitrary-ness of a file that makes it such a good way to define an access control boundary. The problem with something like typeprivate is that, if the enclosing type doesn’t quite encompass the code that ought to have access to the declaration, you either need to move declarations into/out of the type to grant/restrict access, or you need to abandon typeprivate. If you do the former, you’re contorting the design of your types to fit into the access control system, which can ha…

\* No, not you `private`. You're stealing `fileprivate`'s place again... 😑

* * *

Digression aside, I'm not sure I ever have a problem with one part of the project accessing other parts because of them being `internal`. I do get somewhat paranoid in the beginning, but nothing ever comes out of it, even as the projects grow in size.

Though all these talks about _security_ and _trust_ make me think I might be missing out on some fun people are having. I mean, access control is such an easy thing to bypass that they're usually more about convenience than concerns.

---

<div class="post-metadata">

**Author:** ![1-877-547-7272](https://avatars.discourse-cdn.com/v4/letter/1/278dde/32.png) [@1-877-547-7272](https://forums.swift.org/u/1-877-547-7272)\
**Post date:** [December 14, 2021, 4:38am UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/18 "2021-12-14T04:38:02Z")

</div>

> [@tclementdev](#):
>
> Well the point of my post is that I am arguing this is _bad_ because real-world codebase ends up using what is clearly the wrong access modifier, as those members become exposed to other types in the module once they become `internal` . Developers, as human beings, have a liking in tidying up things in their own places, this seems to have been overlooked.

In my experience, `internal` or `public` are almost always the right access modifiers. Most Swift projects I've seen use these two modifiers extensively. The ability to access one type's properties and methods from within another type has never become an issue for me.

I only use `fileprivate` or `private` if there's _absolutely no reason_ to access a property or method outside of the type/file (i.e. `@State` properties in SwiftUI).

> [@QuinceyMorris](#):
>
> My preference would be for some kind of hierarchical sub-module system.

I’ve found that [local Swift packages](https://developer.apple.com/documentation/swift_packages/organizing_your_code_with_local_packages) are a good way to organize modules hierarchically.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [December 14, 2021, 8:15am UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/19 "2021-12-14T08:15:27Z")

</div>

> [@QuinceyMorris](#):
>
> I don't see exactly how `fileprivate` helps that much. Maybe something like `private("additionalFileName.swift")` could be a way of granting access.

A different non-file based approach could be a more stricter form of extension that is being granted.

```
struct Thing {
    vetted extensions Foo, Bar // preliminary new syntax
    private var x = 0
    private func y() {}
}

// same file as Thing
extension Thing { // normal extension
    func yy() {
        x = 1 // Error, x is private
    }
}

// same or different file
vetted extension Thing(Foo) { // preliminary new syntax
    named extensions Baz // preliminary new syntax
    private var w = 1 // variables allowed
    private func z() {
        x = 1 // ok
    }
}

// same or different file
vetted extension Thing(Baz) { // preliminary new syntax
    private func t() {
        x = 1 // ok
        w = 1 // ok
    }
}

// same or different file
vetted extension Thing(AttemtToBreachSecurity) { // Error, not allowed
}

```

real-life analogy would be: not everyone can extend my house, only those whom I granted that permission. And if the vetted builder wants so they can hire a subcontractor.

The added benefit is an ability to add new variables in these vetted extensions.

---

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [December 14, 2021, 9:41am UTC](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029/20 "2021-12-14T09:41:47Z")

</div>

The problem with this, and any other attempt to allow scoped multifile access to a member, is that anyone can just add a public version of the member in one of your allowed extensions. It's no more "secure" than the internal version, but half as convenient.

```swift
struct Thing {
    vetted extensions Foo, Bar // preliminary new syntax
    private var x = 0
    private func y() {}
}

// same file as Thing
extension Thing { // normal extension
    mutating func yy() {
        x = 1 // Error, x is private
    }
}

// same or different file
vetted extension Thing(Foo) { // preliminary new syntax
    named extensions Baz // preliminary new syntax
    private var w = 1 // variables allowed
    private mutating func z() {
        x = 1 // ok
    }
    // This is going to be legal no matter how you attempt to specify
    // who can do what.
    public var pubX: Int {
        get { x }
        set { x = newValue }
    }
}

```

Any added safety by using private is completely illusory if you have any method of accessing a private member from another file.

And the only security you get from single file private is that you only have to vet one file to make sure no one is exposing things they shouldn't be, instead of every other file in the project.

[Next page](https://forums.swift.org/t/calling-private-methods-from-extensions-in-separate-files/54029.md?page=2)
