Skip to content

Instantly share code, notes, and snippets.

@magnuskahr
Last active April 1, 2022 06:56
Show Gist options
  • Save magnuskahr/4296ba090931f139172ed5d94e79b2e0 to your computer and use it in GitHub Desktop.
Save magnuskahr/4296ba090931f139172ed5d94e79b2e0 to your computer and use it in GitHub Desktop.

SE-0401: unimport for cleaning up files

Introduction

Initialization and deinitalization are important parts of how we create structs and classes in Swift. Being a bit more abstract, we have files that can import other modules to expand local capabilities using the import keyword, however, the reversed ain’t true, requiring developers to hassle with imported functionality at lines were it ain’t used. The unimport keyword expands the capabilities of swift to unimport a module, and allow a very targeted and optimized flow of code.

Motivation

The import keyword is used widely in Swift to import other modules, and will become increasingly important as the diversity of the Swift Package Manager extends the languages capabilities, to allow development of functionality, modularisation, and having propper access control. However, the language has not kept up with the importance of using the import keyword, as if it is used unwisely can clutter our code and even make it uncompilable. From structs and classes we have the pairs init and deinit, where we can initialise and clean up our objects and data. It is now time for our files to have the same luxury, introducing the unimport keyword into Swift.

With this new keyword, we can keep imports extremely targeted and make sure we only have access to what we really need.

import UIKit
final class PaymentViewController: UIViewController {
    func perform(payment: Payment) {}
}
unimport UIKit

struct Payment {
    let amount: Double
} 

Proposed solution

Swift should come with a built in typealias for unimport, simply bringing the negation of import:

typealias unimport = !import

Detailed design

Being a simple negation, Swift gains all the functionality of import, just negated, for free.

Meaning that, when we in a file don’t need UIKit anymore, we can unimport the framework and regain the used RAM, making our models or network code have more resources available at hand.

The unimport keyword can also be used to fix compile errors. Imagine we have an SPM called Core, with the following code:

struct Binding<Value> {
    let value: Value
}

If we import both Core and SwiftUI, we will now get trouble using Binding, with the following code which won't compile:\

import SwiftUI
import Core

struct AView: View {
    var value: Binding<String>
    var body: some View {
        Text(value)
    }
}

Using unimport we can fix this, and make the code compile, as we can unimport the Binding struct from SwiftUI:

import SwiftUI
// Using unimport to remove the imported Binding from SwiftUI
unimport struct SwiftUI.Binding
import Core

struct AView: View {
    var value: Binding<String>
    var body: some View {
        Text(value)
    }
}

Source compatibility

This change is purely additive and does not break source compatibility of any valid existing Swift code.

Effect on ABI stability

This change is purely additive, and is a syntactic transformation to existing valid code, so has no effect on ABI stability.

Effect on API resilience

This change is purely additive, and is a syntactic transformation to existing valid code, so has no effect on ABI stability.

Effect on fools

Only in april

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment