Sent from my iPhone

> On 30 Nov 2016, at 06:40, David Hart via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> For example, here is a design pattern I would find clearer with explicit type 
> information:
> 
> let cat = factory.get<Cat>()
> 
> vs
> 
> let cat: Cat = factory.get()
> 
> Having the explicit type information in angle brackets allows us to move the 
> type information closer to where it make sense.
> 

Agreed :).

> 
>>> On 29 Nov 2016, at 23:52, Douglas Gregor via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> 
>>> On Nov 29, 2016, at 8:00 AM, Derrick Ho via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> I don't think the angle brackets adds any additional benefit than adding 
>>> the type information as a parameter.  Adding Angle brackets will just make 
>>> it more crowded….
>> 
>> Adding the type information as a parameter effectively disables type 
>> inference for that parameter, because you have to pass the parameter 
>> explicitly. In some cases, like the unsafeBitCast function I pointed out, 
>> that is a good thing. In other cases, type inference might do the right 
>> thing for most callers, but specific call sites want the extra control 
>> provided by explicitly specifying generic arguments. That’s how I see this 
>> proposal: not as a replacement for the metatype parameter idiom that 
>> unsafeBitCast uses, but as a way to be more explicit at particular call 
>> sites when type inference either fails (e.g., due to lack of contextual type 
>> information), produces a result different than what is desired, or is 
>> sufficiently complicated that the call site requires more documentation.
>> 
>>> plus, the syntax just seems too much like c++
>> 
>> Lots of languages use angle brackets like this; Swift has it for types 
>> already, so I find this an odd criticism.
>> 
>>      - Doug
>> 
>>> On Tue, Nov 29, 2016 at 8:43 AM Goffredo Marocchi via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> I think this is a case where the angle bran jets is both more readable and 
>>> terse without losing context... opinions and all :).
>>> 
>>> Sent from my iPhone
>>> 
>>>> On 29 Nov 2016, at 09:47, Andrew Trick via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> 
>>>> 
>>>>>> On Nov 28, 2016, at 10:11 PM, Douglas Gregor via swift-evolution 
>>>>>> <swift-evolution@swift.org> wrote:
>>>>>> 
>>>>>> 
>>>>>> On Nov 21, 2016, at 3:05 PM, Ramiro Feria Purón via swift-evolution 
>>>>>> <swift-evolution@swift.org> 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…
>>>> 
>>>> Angle brackets in function calls are hideous. This is objectively more 
>>>> clear and much prettier IMO:
>>>> 
>>>>   unsafeBitCast(something, to: Int)
>>>> 
>>>>> it would enable type inference to go wild with unsafe casts:
>>>>> 
>>>>>   foo(unsafeBitCast(something))   // just cast it to.. whatever   
>>>>> 
>>>>> which is… not great.
>>>>> 
>>>>> I’d like one bit of clarification in the proposal. Right now, one is not 
>>>>> permitted to have a type parameter in a generic function that isn’t used 
>>>>> somewhere in its signature, e.g.,
>>>>> 
>>>>>   func f<T>() -> Void { … }   // error: T is not part of the signature of 
>>>>> f()
>>>>> 
>>>>> This restriction is obvious in today’s Swift, because there is absolutely 
>>>>> no way one could ever use this function. With your proposed extension, it 
>>>>> would be possible to use this function. Does the restriction remain or is 
>>>>> it lifted?
>>>>> 
>>>>> Personally, I’d like the restriction to stay, because it feels like such 
>>>>> functions fall into the same camp as unsafeBitCast: if the type parameter 
>>>>> affects how the function operates but is *not* part of its signature, 
>>>>> then it should be expressed like a normal parameter (of a metatype). It 
>>>>> also helps provide better diagnostics when changing a generic function to 
>>>>> no longer require one of its type parameters.
>>>> 
>>>> +1 for required type parameters being normal parameters.
>>>> 
>>>> I think the case mentioned in the proposal reads much better as:
>>>> 
>>>>   processAll(in: vehicles, as: Bicycle, condition: aboveSpeedLimit)
>>>> 
>>>> If angle brackets can be limited to generic definitions and type names, 
>>>> that’s a great accomplishment.
>>>> 
>>>> -Andy
>>>> 
>>>>> 
>>>>> And, as Dave notes, it’s effectively syntactic sugar, so it belongs in 
>>>>> Swift 4 stage 2.
>>>>> 
>>>>>   - Doug
>>>>> 
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution@swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to