<div dir="ltr"><i><span style="font-size:13px">I might even be willing to inhibit deduction,</span><br class="gmail_msg" style="font-size:13px"><span style="font-size:13px">by default, of all generic function type parameters that don't appear in</span><br class="gmail_msg" style="font-size:13px"><span style="font-size:13px">the parameter list.</span></i><div><br></div><div>^ If this was adopted, what Dave is proposing is:</div><div><br></div><div><span class="gmail_msg" style="font-family:menlo;font-size:11px;font-variant-ligatures:no-common-ligatures;color:rgb(4,51,255)">func</span><span class="gmail_msg" style="font-family:menlo;font-size:11px;font-variant-ligatures:no-common-ligatures"> f<T>(</span><span class="gmail_msg" style="font-family:menlo;font-variant-ligatures:no-common-ligatures"><span style="font-size:11px">) -> </span><font color="#3495af"><span style="font-size:11px">T</span><font size="1"> </font></font></span><span style="color:rgb(0,143,0);font-family:menlo;font-size:11px">// error: generic parameter T must be explicit</span></div><div><span class="gmail_msg" style="font-family:menlo;font-size:11px;font-variant-ligatures:no-common-ligatures;color:rgb(4,51,255)">func</span><span class="gmail_msg" style="font-family:menlo;font-size:11px;font-variant-ligatures:no-common-ligatures"> f<<span class="gmail_msg" style="color:rgb(4,51,255)">explicit</span> T>(</span><span class="gmail_msg" style="font-family:menlo;font-size:11px;font-variant-ligatures:no-common-ligatures">) -> <font color="#3495af">T </font></span><span style="color:rgb(0,143,0);font-family:menlo;font-size:11px">// ok</span></div><div><br></div><div> <br><br><div class="gmail_quote"><div dir="ltr">On Thu, 1 Dec 2016 at 11:17 Dave Abrahams via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br class="gmail_msg">
on Mon Nov 28 2016, Douglas Gregor <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:<br class="gmail_msg">
<br class="gmail_msg">
>> On Nov 21, 2016, at 3:05 PM, Ramiro Feria Purón via swift-evolution<br class="gmail_msg">
> <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:<br class="gmail_msg">
>><br class="gmail_msg">
>> Problem:<br class="gmail_msg">
>><br class="gmail_msg">
>> Currently, it is not possible to be explicit about the generic parameters (type parameters) in a<br class="gmail_msg">
> generic function call. Type parameters are inferred from actual parameters:<br class="gmail_msg">
><br class="gmail_msg">
>><br class="gmail_msg">
>> func f<T>(_ t: T) {<br class="gmail_msg">
>><br class="gmail_msg">
>> //..<br class="gmail_msg">
>> }<br class="gmail_msg">
>><br class="gmail_msg">
>> f(5) // T inferred to be Int<br class="gmail_msg">
>> f("xzcvzxcvx") // T inferred to be string<br class="gmail_msg">
>><br class="gmail_msg">
>> 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:<br class="gmail_msg">
>><br class="gmail_msg">
>> func g<T>(_ x: Int) -> [T] {<br class="gmail_msg">
>><br class="gmail_msg">
>> var result: [T] = []<br class="gmail_msg">
>><br class="gmail_msg">
>> //..<br class="gmail_msg">
>><br class="gmail_msg">
>> return result<br class="gmail_msg">
>> }<br class="gmail_msg">
>><br class="gmail_msg">
>> In such cases, the type parameters must be inferrable from the context:<br class="gmail_msg">
>><br class="gmail_msg">
>> g(7) // Error: T cannot be inferred<br class="gmail_msg">
>> let array = g(7) // Error: T cannot be inferred<br class="gmail_msg">
>> let array: [String] = g(7) // Ok: T inferred to be String<br class="gmail_msg">
>> let array = g<String>(7) // Error: Cannot explicitly specialise generic function<br class="gmail_msg">
>><br class="gmail_msg">
>><br class="gmail_msg">
>><br class="gmail_msg">
>> Proposed Solution:<br class="gmail_msg">
>><br class="gmail_msg">
>> Allow explicit type parameters in generic function call:<br class="gmail_msg">
>><br class="gmail_msg">
>> let _ = g<String>(7) // Ok<br class="gmail_msg">
>><br class="gmail_msg">
>><br class="gmail_msg">
>><br class="gmail_msg">
>> Motivation:<br class="gmail_msg">
>><br class="gmail_msg">
>> Consider the following contrived example:<br class="gmail_msg">
>><br class="gmail_msg">
>> class Vehicle {<br class="gmail_msg">
>> var currentSpeed = 0<br class="gmail_msg">
>> //..<br class="gmail_msg">
>> }<br class="gmail_msg">
>><br class="gmail_msg">
>> class Bicycle: Vehicle {<br class="gmail_msg">
>> //..<br class="gmail_msg">
>> }<br class="gmail_msg">
>><br class="gmail_msg">
>> class Car: Vehicle {<br class="gmail_msg">
>> //..<br class="gmail_msg">
>> }<br class="gmail_msg">
>><br class="gmail_msg">
>> @discardableResult<br class="gmail_msg">
>> func processAll<T: Vehicle>(in vehicles: [Vehicle], condition: (Vehicle) -> Bool) -> [T] {<br class="gmail_msg">
>><br class="gmail_msg">
>> var processed: [T] = []<br class="gmail_msg">
>><br class="gmail_msg">
>> for vehicle in vehicles {<br class="gmail_msg">
>> guard let t = vehicle as? T, condition(vehicle) else { continue }<br class="gmail_msg">
>> //..<br class="gmail_msg">
>> processed.append(t)<br class="gmail_msg">
>> }<br class="gmail_msg">
>><br class="gmail_msg">
>> return processed<br class="gmail_msg">
>> }<br class="gmail_msg">
>><br class="gmail_msg">
>> func aboveSpeedLimit(vehicle: Vehicle) -> Bool {<br class="gmail_msg">
>> return vehicle.currentSpeed >= 100<br class="gmail_msg">
>> }<br class="gmail_msg">
>><br class="gmail_msg">
>><br class="gmail_msg">
>> let processedVehicles = processAll(in: vehicles, condition: aboveSpeedLimit) // Uh, T inferred to<br class="gmail_msg">
> be Vehicle!<br class="gmail_msg">
>> let processedCars: [Car] = processAll(in: vehicles, condition: aboveSpeedLimit) // T inferred to<br class="gmail_msg">
> be Car<br class="gmail_msg">
>> processAll<Bicycle>(in: vehicles, condition: aboveSpeedLimit) // This should be allowed under this<br class="gmail_msg">
> proposal<br class="gmail_msg">
>><br class="gmail_msg">
>><br class="gmail_msg">
>> Notes:<br class="gmail_msg">
>><br class="gmail_msg">
>> If necessary, the (real life) Swift code that lead to the proposal could be shared.<br class="gmail_msg">
><br class="gmail_msg">
> This seems completely reasonable to me. I had always expected us to<br class="gmail_msg">
> implement this feature, but we never got around to it, and it wasn’t a<br class="gmail_msg">
> high priority because one can always use type inference. Additionally,<br class="gmail_msg">
> there were a few places where we originally thought we wanted this<br class="gmail_msg">
> feature, but prefer the more-explicit form where the user is required<br class="gmail_msg">
> to explicitly pass along a metatype. unsafeBitCast is one such case:<br class="gmail_msg">
><br class="gmail_msg">
> func unsafeBitCast<T, U>(_ x: T, to: U.Type) -> U<br class="gmail_msg">
><br class="gmail_msg">
> Even if we had the ability to provide explicit type arguments, we<br class="gmail_msg">
> would *not* want to change this signature to<br class="gmail_msg">
><br class="gmail_msg">
> func unsafeBitCast<U, T>(_ x: T) -> U // bad idea<br class="gmail_msg">
><br class="gmail_msg">
> because while it makes the correct usage slightly cleaner:<br class="gmail_msg">
><br class="gmail_msg">
> unsafeBitCast<Int>(something) // slightly prettier, but...<br class="gmail_msg">
><br class="gmail_msg">
> it would enable type inference to go wild with unsafe casts:<br class="gmail_msg">
><br class="gmail_msg">
> foo(unsafeBitCast(something)) // just cast it to.. whatever<br class="gmail_msg">
><br class="gmail_msg">
> which is… not great.<br class="gmail_msg">
<br class="gmail_msg">
Yeah, but IMO ideally we'd have a way to inhibit deduction of some<br class="gmail_msg">
generic type parameters. I might even be willing to inhibit deduction,<br class="gmail_msg">
by default, of all generic function type parameters that don't appear in<br class="gmail_msg">
the parameter list.<br class="gmail_msg">
<br class="gmail_msg">
--<br class="gmail_msg">
-Dave<br class="gmail_msg">
<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div></div></div>