[swift-evolution] [Pitch] Richer function identifiers, simpler function types

Pyry Jahkola pyry.jahkola at iki.fi
Thu Apr 28 06:16:07 CDT 2016

Corrections, additions below…

> Let's consider the following declarations:
>     class Bar {
>         func baz()                   // #8 Method named 'Bar.baz(_)' with type 'Bar -> () -> ()'.
>         func baz(x y: Int)           // #9 Method named 'Bar.baz(x:)' with type 'Bar -> Int -> ()'.
>         static func baz(x: Int = 0)  // #10 Static method named 'Bar.Self.baz(x:)' with type 'Int -> ()'.
>     }
>     // ...
>     let bar = Bar()
>     let f10 = bar.baz                // error: not a function reference, did you mean 'bar.baz(_)' or 'bar.baz(x:)'?
>     let f11 = bar.baz(_)             // #18 Function synonymous to the closure '{ bar.baz() }' with type '() -> ()'.
>     let f12 = bar.baz(x:)            // #19 Function synonymous to the closure '{ bar.baz(x: $0) }' with type 'Int -> ()'.
>     let f13 = Bar.Self.baz(x:)       // #20 Function synonymous to the closure '{ Bar.baz(x: $0) }' with type 'Int -> ()'.
>     let f14 = Bar.Self.baz(_)        // #21 Function synonymous to the closure '{ Bar.baz() }' with type '() -> ()'.


> C2: Extend SE-0021 <https://github.com/apple/swift-evolution/blob/master/proposals/0021-generalized-naming.md> by removing the ambiguity between instance and type members. From now on, `Bar.baz(_)` 

That was meant to read:

"(…) From now on, `Bar.baz(_)` unambiguously refers to the instance method named `baz(_)`. To refer to the static or class method named `baz(_)`, put the keyword `.Self` between the type and the base name. This syntax should align with the outcome of SE-0068 <https://github.com/apple/swift-evolution/blob/master/proposals/0068-universal-self.md> such the keyword resembles the static method call `thing.Self.baz()` of a `thing` of type `Bar`."

(Alternatives considered: (1) the use of `Bar.self.baz(_)` with lower-case `self`, which is probably more confusing; and (2) inverting the choice and making the instance method require a keyword instead, which would harm readability as it's usually the instance method that you'd refer to and not the static one.)

> C6: Clarify that by using the base name `foo` for a function, the same scope cannot define a variable with the name `foo`. And, vice versa, in a scope that defines a variable named `foo`, there can be no function `foo(...)` defined at the same scope level.

This doesn't prevent shadowing of course. E.g. An inner scope with a variable named `foo` would shadow all functions named `foo(...)` of an enclosing scope.

> The implications are:
> I1: The use of a function's base name to refer to a function will cease to work. It has, however, been buggy up to this date. Consider the following:
>     let f = [Int].prefix // '[Int] -> Int -> ArraySlice<Int>'
>     let g1 = [Int].dropFirst // Inexplicably chooses the '[Int] -> Int -> ArraySlice<Int>' overload!
>     let g2 = [Int].dropFirst as [Int] -> () -> ArraySlice<Int> // Disambiguate by type.
>     let h1 = [Int].sorted // Chooses the '[Int] -> () -> [Int]' overload, unlike 'dropFirst' above.
>     let h2 = [Int].sorted as [Int] -> ((Int, Int) -> Bool) -> [Int] // Disambiguate by type.

By the way, the same also happens with the current Swift (both 2.2 and 3 master) when referring to the partially applied instance method like so:

    let xs = [1,3,2]
    let g = xs.dropFirst // Chooses the 'Int -> ArraySlice<Int>' overload.
    let h = xs.sorted    // Chooses the '() -> [Int]' overload, unlike 'dropFirst' above.

> I3: Function argument lists are no longer that special and there's no need to notate single-n-tuple argument lists separately from n-argument functions, i.e. SE-0066 <https://github.com/apple/swift-evolution/blob/master/proposals/0066-standardize-function-type-syntax.md> is not really needed anymore. The new intuition here is that it's the function's name that defines how a function can be called, not its type.

In yet other words, we don't have to capture the arity of a function in the type system at all—it's enough to carry that information around in the function name.


Finally, this was a fairly technical pitch but a pitch anyway. Any ideas pro or against?

— Pyry

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160428/ecb01a5b/attachment.html>

More information about the swift-evolution mailing list