Implicit parameters...?

I really like what this idea enables. But when presented as implicit, it does not feel Swifty. How about we present your idea with a different terminology:

Lets start by looking at what we can already do with default parameter values:

class Context { /* ... */ }

var context = Context()

struct Shape {
    func draw(into context: Context = context) { /* ... */ }
    //                                ^^^^^^^ default is a global var
}

class DebugContext: Context { /* ... */ }

let shape = Shape()

do {
    shape.draw() // Draws to a `Context`
    let currentContext = context; defer { context = currentContext }
    context = DebugContext()
    shape.draw() // Draws to a `DebugContext`
}

This has serious issues, but we can improve it by defining a new kind of default parameter value. I call it a declared default, where we declare the identifier as representing the default value instead of providing an expression. Here is how it would look:

class Context { /* ... */ }

struct Shape {
    func draw(into context: Context = default )  // `context` identifier is declared to represent the default value
       { /* ... */ }                             // This syntax eliminates "What about default for implicit parameter?" question.
}

class DebugContext: Context { /* ... */ }

let default context = Context() // Only `let` binding; override by shadowing in scope

do {
    let shape = Shape()
    shape.draw() // uses the default `context` from outer scope. if no default was declared, the `context` parameter would be required.
    let default context = DebugContext()
    shape.draw() // draws to the `DebugContext` from local scope
    // We can also explicitly provide the parameter:
   let otherContext = Context
   shape.draw(into: otherContext)
}
shape.draw() // back to using the `Context` from global scope, just like any identifier.

I would also want to let protocols declare default identifiers for parameter values:

protocol Shape {
    func draw(into context: Context = default ) 
}

What do you think?

3 Likes