[swift-evolution] Pitch: Compound name `foo(:)` for nullary functions

David Hart david at hartbit.com
Sat Feb 25 15:43:01 CST 2017


> On 25 Feb 2017, at 00:56, Jordan Rose via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I don't have a good answer for this, but I'll vote against 'foo(:)' because that's what a lot of people think the name of 'foo(_:)' should be. I'd rather be able to offer fix-its for that even when you have both 'foo()' and 'foo(_:)' defined. I'd rather go with 'foo(_)' despite the tiny ambiguity in pattern contexts.
> 
> (I'm personally in favor of killing unapplied function references altogether in favor of closures, on the grounds that they are overly terse, make type-checking more complicated, and often lead to retain cycles. Then we'd only need this for #selector, and it's perfectly unambiguous to use 'foo()' there. But I wasn't planning to fight that particular battle now, and it is rather annoying to require the 'as' in the meantime.)

It is potentially going to be hard to fight that battle. I think a lot of functional/Haskell people love them and would be sad to see them go away (I plead guilty). But it isn’t a well known part of the language so I don’t think the general community would miss it.

> Jordan
> 
> 
>> On Feb 21, 2017, at 23:05, Jacob Bandes-Storch <jtbandes at gmail.com <mailto:jtbandes at gmail.com>> wrote:
>> 
>> Evolutioniers,
>> 
>> Compound name syntax — foo(_:), foo(bar:), foo(bar:baz:) — is used to disambiguate references to functions. (You might've used it inside a #selector expression.) But there's currently no compound name for a function with no arguments.
>> 
>>     func foo() {}  // no compound syntax for this one :(
>>     func foo(_ bar: Int) {}  // foo(_:)
>>     func foo(bar: Int) {}  // foo(bar:)
>>     func foo(bar: String, baz: Double) {}  // foo(bar:baz:)
>> 
>> Given these four functions, only the first one has no compound name syntax. And the simple reference "let myfn = foo" is ambiguous because it could refer to any of the four. A workaround is to specify a contextual type, e.g. "let myfn = foo as () -> Void".
>> 
>> I filed SR-3550 <https://bugs.swift.org/browse/SR-3550> for this a while ago, and there was some discussion in JIRA about it. I'd like to continue exploring solutions here and then write up a formal proposal.
>> 
>> To kick off the discussion, I'd like to propose foo(:) for nullary functions.
>> 
>> Advantages:
>> - the colon marks a clear similarity to the foo(bar:) form when argument labels are present.
>> - cutely parallels the empty dictionary literal, [:].
>> 
>> Disadvantages:
>> - violates intuition about one-colon-per-argument.
>> - the parallel between #selector(foo(:)) and @selector(foo) is not quite as obvious as between #selector(foo(_:)) and @selector(foo:).
>> 
>> 
>> For the sake of discussion, another option would be foo(_). This was my original choice, and I like that the number of colons matches the number of parameters. However, it's a little less obvious as a function reference. It would preclude _ from acting as an actual identifier, and might conflict with pattern-matching syntax (although it appears functions can't be compared with ~= anyway).
>> 
>> 
>> Looking forward to everyone's bikeshed color ideas,
>> Jacob
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


More information about the swift-evolution mailing list