Section 1/102 menit

1. Apa Itu Swift Macro?

1. Apa Itu Swift Macro?

Swift Macro adalah fitur yang memungkinkan kita menulis kode yang menghasilkan kode lain secara otomatis pada saat kompilasi (compile time). Berbeda dengan runtime metaprogramming, macro bekerja sepenuhnya sebelum program dijalankan — artinya tidak ada overhead performa saat aplikasi berjalan.

Masalah yang Diselesaikan Macro

Bayangkan kamu memiliki puluhan struct model yang semuanya perlu konformitas Equatable, Hashable, dan Codable dengan logika kustom. Tanpa macro:

swift
// ❌ TANPA MACRO: boilerplate yang membosankan dan rawan human error
struct User {
    let id: UUID
    let name: String
    let email: String
}

extension User: Equatable {
    static func == (lhs: User, rhs: User) -> Bool {
        lhs.id == rhs.id &&
        lhs.name == rhs.name &&
        lhs.email == rhs.email
    }
}

extension User: Hashable {
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
        hasher.combine(name)
        hasher.combine(email)
    }
}

Dengan macro, semua boilerplate di atas bisa diganti satu baris:

swift
// ✓ DENGAN MACRO: bersih, ekspresif, tidak ada human error
@AutoEquatableHashable
struct User {
    let id: UUID
    let name: String
    let email: String
}

Perbedaan dengan Tools Code Generation Lain

Aspek Swift Macro Sourcery Build Phase Script
Integrasi toolchain Resmi, built-in Eksternal, butuh install Kustom, manual
Type safety ✓ Penuh (AST-level) Terbatas (template string) Tidak ada
IDE support ✓ Expand Macro di Xcode Terbatas Tidak ada
Error message ✓ Lokasi akurat Kurang akurat Tidak ada
Testing ✓ Unit testable Terbatas Tidak ada
Sandbox ✓ Isolated execution Tidak ada Tidak ada

Analogi Sederhana

Bayangkan macro seperti asisten arsitek yang membaca blueprint bangunan kamu, lalu secara otomatis melengkapi gambar teknis yang repetitif (denah listrik, denah plumbing) mengikuti standar yang telah ditetapkan — sebelum konstruksi dimulai. Kamu hanya menulis "saya butuh sistem listrik standar", dan asisten menghasilkan gambar lengkapnya.

Contoh Pertama: #stringify (Built-in Example)

Apple menyertakan contoh macro #stringify di Swift Package template:

swift
// Definisi macro (di sisi implementor)
@freestanding(expression)
public macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(
    module: "MyMacrosMacros",
    type: "StringifyMacro"
)

// Penggunaan (di sisi pengguna)
let (result, code) = #stringify(1 + 2)
print(result) // 3
print(code)   // "1 + 2"

// Setelah expansion, compiler melihat:
let (result, code) = (1 + 2, "1 + 2")

Macro #stringify membaca ekspresi kamu sebagai AST node, lalu menghasilkan tuple yang berisi nilai asli dan representasi string-nya — semua ini terjadi di compile time.