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

Paul Cantrell cantrell at pobox.com
Thu Jan 28 12:00:18 CST 2016


> On Jan 28, 2016, at 12:30 AM, Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org> wrote:
> 
>> Remove implicit tuple splat behavior from function applications
> 
> Please do not remove this without providing an alternative.
> 
> 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.

Brent — Not sure how it all plays out, but would it work for you to use tuples to make all the functions in your chain take a single arg? e.g.:

   private func recordAllocatorWithVersionMemory(args: (versionMemory: CloudDatabaseVersionMemoryType?, typeName: String, _ cloudValue: CloudValue)) throws -> (CKRecord, CloudValue)

   private func writeAttributesAndReferencesToRecord(args: (record: CKRecord, cloudValue: CloudValue))

P


More information about the swift-evolution mailing list