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. > On 29 Nov 2016, at 23:52, Douglas Gregor via swift-evolution > <[email protected]> wrote: > > >> On Nov 29, 2016, at 8:00 AM, Derrick Ho via swift-evolution >> <[email protected] <mailto:[email protected]>> 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 >> <[email protected] <mailto:[email protected]>> 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 >> <[email protected] <mailto:[email protected]>> wrote: >> >>> >>>> On Nov 28, 2016, at 10:11 PM, Douglas Gregor via swift-evolution >>>> <[email protected] <mailto:[email protected]>> wrote: >>>> >>>>> >>>>> On Nov 21, 2016, at 3:05 PM, Ramiro Feria Purón via swift-evolution >>>>> <[email protected] <mailto:[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… >>> >>> 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 >>>> [email protected] <mailto:[email protected]> >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] <mailto:[email protected]> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] <mailto:[email protected]> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] <mailto:[email protected]> >> https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ > 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
