<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&#39;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&lt;T&gt;(</span><span class="gmail_msg" style="font-family:menlo;font-variant-ligatures:no-common-ligatures"><span style="font-size:11px">) -&gt; </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&lt;<span class="gmail_msg" style="color:rgb(4,51,255)">explicit</span> T&gt;(</span><span class="gmail_msg" style="font-family:menlo;font-size:11px;font-variant-ligatures:no-common-ligatures">) -&gt; <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 &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; 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 &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br class="gmail_msg">
<br class="gmail_msg">
&gt;&gt; On Nov 21, 2016, at 3:05 PM, Ramiro Feria Purón via swift-evolution<br class="gmail_msg">
&gt; &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; Problem:<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; Currently, it is not possible to be explicit about the generic parameters (type parameters) in a<br class="gmail_msg">
&gt; generic function call. Type parameters are inferred from actual parameters:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; func f&lt;T&gt;(_ t: T) {<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;     //..<br class="gmail_msg">
&gt;&gt; }<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; f(5)            // T inferred to be Int<br class="gmail_msg">
&gt;&gt; f(&quot;xzcvzxcvx&quot;)  // T inferred to be string<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; 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">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; func g&lt;T&gt;(_ x: Int) -&gt; [T] {<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;     var result: [T] = []<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;     //..<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;     return result<br class="gmail_msg">
&gt;&gt; }<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; In such cases, the type parameters must be inferrable from the context:<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; g(7)                            // Error: T cannot be inferred<br class="gmail_msg">
&gt;&gt; let array = g(7)                // Error: T cannot be inferred<br class="gmail_msg">
&gt;&gt; let array: [String] = g(7)      // Ok: T inferred to be String<br class="gmail_msg">
&gt;&gt; let array = g&lt;String&gt;(7)        // Error: Cannot explicitly specialise generic function<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; Proposed Solution:<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; Allow explicit type parameters in generic function call:<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; let _ = g&lt;String&gt;(7)            // Ok<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; Motivation:<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; Consider the following contrived example:<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; class Vehicle {<br class="gmail_msg">
&gt;&gt;     var currentSpeed = 0<br class="gmail_msg">
&gt;&gt;     //..<br class="gmail_msg">
&gt;&gt; }<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; class Bicycle: Vehicle {<br class="gmail_msg">
&gt;&gt;     //..<br class="gmail_msg">
&gt;&gt; }<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; class Car: Vehicle {<br class="gmail_msg">
&gt;&gt;     //..<br class="gmail_msg">
&gt;&gt; }<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; @discardableResult<br class="gmail_msg">
&gt;&gt; func processAll&lt;T: Vehicle&gt;(in vehicles: [Vehicle], condition: (Vehicle) -&gt; Bool) -&gt; [T] {<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;     var processed: [T] = []<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;     for vehicle in vehicles {<br class="gmail_msg">
&gt;&gt;         guard let t = vehicle as? T, condition(vehicle) else { continue }<br class="gmail_msg">
&gt;&gt;         //..<br class="gmail_msg">
&gt;&gt;         processed.append(t)<br class="gmail_msg">
&gt;&gt;     }<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;     return processed<br class="gmail_msg">
&gt;&gt; }<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; func aboveSpeedLimit(vehicle: Vehicle) -&gt; Bool {<br class="gmail_msg">
&gt;&gt;     return vehicle.currentSpeed &gt;= 100<br class="gmail_msg">
&gt;&gt; }<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; let processedVehicles = processAll(in: vehicles, condition: aboveSpeedLimit) // Uh, T inferred to<br class="gmail_msg">
&gt; be Vehicle!<br class="gmail_msg">
&gt;&gt; let processedCars: [Car] = processAll(in: vehicles, condition: aboveSpeedLimit) // T inferred to<br class="gmail_msg">
&gt; be Car<br class="gmail_msg">
&gt;&gt; processAll&lt;Bicycle&gt;(in: vehicles, condition: aboveSpeedLimit) // This should be allowed under this<br class="gmail_msg">
&gt; proposal<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; Notes:<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; If necessary, the (real life) Swift code that lead to the proposal could be shared.<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; This seems completely reasonable to me. I had always expected us to<br class="gmail_msg">
&gt; implement this feature, but we never got around to it, and it wasn’t a<br class="gmail_msg">
&gt; high priority because one can always use type inference. Additionally,<br class="gmail_msg">
&gt; there were a few places where we originally thought we wanted this<br class="gmail_msg">
&gt; feature, but prefer the more-explicit form where the user is required<br class="gmail_msg">
&gt; to explicitly pass along a metatype. unsafeBitCast is one such case:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt;       func unsafeBitCast&lt;T, U&gt;(_ x: T, to: U.Type) -&gt; U<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; Even if we had the ability to provide explicit type arguments, we<br class="gmail_msg">
&gt; would *not* want to change this signature to<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt;       func unsafeBitCast&lt;U, T&gt;(_ x: T) -&gt; U     // bad idea<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; because while it makes the correct usage slightly cleaner:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt;       unsafeBitCast&lt;Int&gt;(something)   // slightly prettier, but...<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; it would enable type inference to go wild with unsafe casts:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt;       foo(unsafeBitCast(something))   // just cast it to.. whatever<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; which is… not great.<br class="gmail_msg">
<br class="gmail_msg">
Yeah, but IMO ideally we&#39;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&#39;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>