*I might even be willing to inhibit deduction,by default, of all generic function type parameters that don't appear inthe parameter list.*
^ If this was adopted, what Dave is proposing is: func f<T>() -> T // error: generic parameter T must be explicit func f<explicit T>() -> T // ok On Thu, 1 Dec 2016 at 11:17 Dave Abrahams via swift-evolution < [email protected]> wrote: > > on Mon Nov 28 2016, Douglas Gregor <[email protected]> wrote: > > >> On Nov 21, 2016, at 3:05 PM, Ramiro Feria Purón via swift-evolution > > <[email protected]> wrote: > >> > >> 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. > > > > This seems completely reasonable to me. I had always expected us to > > implement this feature, but we never got around to it, and it wasn’t a > > high priority because one can always use type inference. Additionally, > > there were a few places where we originally thought we wanted this > > feature, but prefer the more-explicit form where the user is required > > to explicitly pass along a metatype. unsafeBitCast is one such case: > > > > func unsafeBitCast<T, U>(_ x: T, to: U.Type) -> U > > > > Even if we had the ability to provide explicit type arguments, we > > would *not* want to change this signature to > > > > func unsafeBitCast<U, T>(_ x: T) -> U // bad idea > > > > because while it makes the correct usage slightly cleaner: > > > > unsafeBitCast<Int>(something) // slightly prettier, but... > > > > it would enable type inference to go wild with unsafe casts: > > > > foo(unsafeBitCast(something)) // just cast it to.. whatever > > > > which is… not great. > > Yeah, but IMO ideally we'd have a way to inhibit deduction of some > generic type parameters. I might even be willing to inhibit deduction, > by default, of all generic function type parameters that don't appear in > the parameter list. > > -- > -Dave > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
