[swift-evolution] Proposal: Remove implicit tuple splat behavior from function applications

Chris Lattner clattner at apple.com
Fri Jan 29 11:41:15 CST 2016

> On Jan 27, 2016, at 10:30 PM, Brent Royal-Gordon <brent at architechies.com> wrote:
>> Remove implicit tuple splat behavior from function applications
> Please do not remove this without providing an alternative.

I understand the desires, but I don’t think that is the right way to go in this case for three reasons:

1. Proposals should be incremental.  Removing this (very rarely used) feature is a prerequisite to adding its replacement, particularly given that the replacement will have different semantics.

2. The proposed addition of the new feature will have to be self-justified based on the merits of that proposal.  Those merits will depend on the exact design.

3. Shipping Swift 3 with this feature, then changing the feature in Swift 4 would break code.  While Swift 4 will probably break *some* code, we really want to reduce cases that happens.  We *know* this feature is wrong as it is, so it is most conservative to remove it now (accepting the breakage in Swift 3 timeframe) and add it back if/when there is a good proposal.


> I use this pretty frequently, usually in combination with higher-order functions like `map` and `filter` when I'm linking together steps in a pipeline. Here's one example where I'm converting structs into CloudKit objects. I have to perform a series of steps: extract the type and value from the instance (and possibly from its child instances), retrieve or allocate CKRecords for each one, and then write the data into the CKRecords. The top-level flow for this is simply:
>    func addInstance(instance: CloudRepresentable, recursively: Bool) throws {
>        try typeNameAndValueForInstance(instance, recursively: recursively).lazy.map(recordAllocatorWithVersionMemory(versionMemory)).forEach(writeAttributesAndReferencesToRecord)
>    }
> Each step in this process is implemented with a private method whose signature matches the methods before and after. This allows me to name each step and encapsulate the details of how they're done. Yes, the signatures are slightly contorted, but they're private methods—implementation details—so it doesn't matter.
>    private func typeNameAndValueForInstance(instance: CloudRepresentable, recursively: Bool) -> [(typeName: String, value: CloudValue)]
>    private func recordAllocatorWithVersionMemory(versionMemory: CloudDatabaseVersionMemoryType?)(typeName: String, _ cloudValue: CloudValue) throws -> (CKRecord, CloudValue)
>    private func writeAttributesAndReferencesToRecord(record: CKRecord, cloudValue: CloudValue)
> I agree that the implicit splat causes problems sometimes, but I don't think it should be removed without an alternative. For my uses, simply being able to say `myFunc.apply` for any function (including the ones provided by SomeType.init) would be sufficient. This method could perhaps be overloaded to support all possible combinations of default argument omissions.
> -- 
> Brent Royal-Gordon
> Architechies

More information about the swift-evolution mailing list