[swift-evolution] Proposal: Allow explicit type parameter specification in generic function call
Adrian Zubarev
adrian.zubarev at devandartist.com
Mon Nov 21 17:35:42 CST 2016
I’m not sure what are you trying to solve here. Your code from the motivation compiles just fine in my Playground.
About the g function:
g(7) as [String]
let _: [String] = g(7)
Personally I don’t like to see <Type> noise on functions in Swift.
--
Adrian Zubarev
Sent with Airmail
Am 22. November 2016 um 00:06:02, Ramiro Feria Purón via swift-evolution (swift-evolution at swift.org) schrieb:
Problem:
Currently, it is not possible to be explicit about the generic parameters (type parameters) in a generic function call. Type parameters are inferred from actual parameters:
func f<T>(_ t: T) {
//..
}
f(5) // T inferred to be Int
f("xzcvzxcvx") // T inferred to be string
If no type parameter is involved in the formal parameters, the type parameter needs to be used somehow as part of the return type. For example:
func g<T>(_ x: Int) -> [T] {
var result: [T] = []
//..
return result
}
In such cases, the type parameters must be inferrable from the context:
g(7) // Error: T cannot be inferred
let array = g(7) // Error: T cannot be inferred
let array: [String] = g(7) // Ok: T inferred to be String
let array = g<String>(7) // Error: Cannot explicitly specialise generic function
Proposed Solution:
Allow explicit type parameters in generic function call:
let _ = g<String>(7) // Ok
Motivation:
Consider the following contrived example:
class Vehicle {
var currentSpeed = 0
//..
}
class Bicycle: Vehicle {
//..
}
class Car: Vehicle {
//..
}
@discardableResult
func processAll<T: Vehicle>(in vehicles: [Vehicle], condition: (Vehicle) -> Bool) -> [T] {
var processed: [T] = []
for vehicle in vehicles {
guard let t = vehicle as? T, condition(vehicle) else { continue }
//..
processed.append(t)
}
return processed
}
func aboveSpeedLimit(vehicle: Vehicle) -> Bool {
return vehicle.currentSpeed >= 100
}
let processedVehicles = processAll(in: vehicles, condition: aboveSpeedLimit) // Uh, T inferred to be Vehicle!
let processedCars: [Car] = processAll(in: vehicles, condition: aboveSpeedLimit) // T inferred to be Car
processAll<Bicycle>(in: vehicles, condition: aboveSpeedLimit) // This should be allowed under this proposal
Notes:
If necessary, the (real life) Swift code that lead to the proposal could be shared.
_______________________________________________
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/20161122/2aaa3504/attachment.html>
More information about the swift-evolution
mailing list