Sounds good :) I’ll mention those in the Alternatives. > On 26 May 2016, at 09:26, Callionica <[email protected]> wrote: > > A perfectly reasonable preference. For me, "as" reads as a potential type > conversion (which I don't want) and specifying the type on the local can be > verbose in cases when a single input or output type is sufficient for > disambiguation. plus1 has 1/3 the number of types specified in the type > deduction operator example than appear in the explicitly typed local or the > as-cast code. Anyway, I hope you will consider all hinting/deduction > techniques as alternatives to your proposal so that you can say why it's > better or if it's solving a different problem. > > -- Callionica > > On May 25, 2016, at 11:43 PM, David Hart <[email protected] > <mailto:[email protected]>> wrote: > >> I personally don't really see the advantage of those deduction operators. I >> would prefer writing: >> >> let plus1: (Int, Int) -> Int = + >> let plus2 = + as ((Int, Int) -> Int) >> >> On 26 May 2016, at 06:11, Callionica (Swift) >> <[email protected] <mailto:[email protected]>> >> wrote: >> >>> I have an alternative you might like to consider: type deduction operators >>> >>> The input type deduction operator lets you put one or more types in front >>> of a function to guide type deduction based on the parameters >>> >>> The output type deduction operator lets you put a type after a function to >>> guide type deduction based on the return type >>> >>> This is a library-only solution that lets you not only select a >>> specialization for a generic function, but also choose an overload from an >>> overload set >>> >>> It's up to the user whether they use input, output, or both type deduction >>> ops and up to them how many types they supply for input. For example, when >>> you know that the overloads or generic functions you're choosing from have >>> two parameters of the same type, you only need to provide a single type to >>> trigger the correct type deduction (shown below with operator+). >>> >>> Here's the basic idea (the specific symbol used is just what I use, could >>> be changed): >>> >>> infix operator >>> { associativity left } >>> >>> // Input type deduction operator >>> func >>> <In, Out>(deduce: In.Type, fn: In -> Out) -> In -> Out { >>> return fn >>> } >>> >>> // Add versions for functions with 2-5 parameters >>> func >>> <In, In2, Out>(deduce: In.Type, fn: (In, In2) -> Out) -> (In, In2) >>> -> Out { >>> return fn >>> } >>> >>> // Add versions for 2-5 inputs >>> func >>> <In, In2, Out>(deduce: (In.Type, In2.Type), fn: (In, In2) -> Out) >>> -> (In, In2) -> Out { >>> return fn >>> } >>> >>> // Output type deduction operator >>> func >>> <In, Out>(fn: In -> Out, deduce: Out.Type) -> In -> Out { >>> return fn >>> } >>> >>> let plus1 = Int.self >>> (+) >>> let plus2 = (Int.self, Int.self) >>> (+) >>> >>> -- Callionica >>> >>> >>> >>> >>> >>> >>> On Wed, May 25, 2016 at 4:17 PM, David Hart via swift-evolution >>> <[email protected] <mailto:[email protected]>> wrote: >>> Hello, >>> >>> This is a new pitch to allow explicitly specializing generic functions. >>> Notice that potential ambiguity with initialisers and how I’m currently >>> trying to avoid it. Please let me know what you think! >>> >>> David >>> >>> Allow explicit specialization of generic functions >>> >>> Proposal: SE-XXXX >>> <https://github.com/apple/swift-evolution/blob/master/proposals/XXXX-allow-explicit-specialization-generic-functions.md> >>> Author: David Hart <https://github.com/hartbit>, Douglas Gregor >>> <https://github.com/DougGregor> >>> Status: TBD >>> Review manager: TBD >>> >>> <https://github.com/hartbit/swift-evolution/tree/allow-explicit-types-generic-functions#introduction>Introduction >>> >>> This proposal allows bypassing the type inference engine and explicitly >>> specializing type arguments of generic functions. >>> >>> >>> <https://github.com/hartbit/swift-evolution/tree/allow-explicit-types-generic-functions#motivation>Motivation >>> >>> In Swift, generic type parameters are inferred by the argument or return >>> value types as follows: >>> >>> func foo<T>(t: T) { ... } >>> >>> foo(5) // infers T = Int >>> There exists certain scenarios when a programmer wants to explicitly >>> specialize a generic function. Swift does not allow it, so we resort to >>> giving hints to the inference engine: >>> >>> let f1 = foo as ((Int) -> Void) >>> let f2: (Int) -> Void = foo >>> let f3 = foo<Int> // error: Cannot explicitly specialize a generic function >>> >>> func bar<T>() -> T { ... } >>> >>> let b1 = bar() as Int >>> let b2: Int = bar() >>> let b3 = bar<Int>() // error: Cannot explicitly specialize a generic >>> function >>> This behaviour is not very consistent with generic types which allow >>> specialization: >>> >>> let array: Array<Int> = Array<Int>(arrayLiteral: 1, 2, 3) >>> Therefore, this proposal seeks to make the above errors valid >>> specializations: >>> >>> let f3 = foo<Int> // explicitly specialized to (Int) -> Void >>> let b3 = bar<Int>() // explicitly specialized to () -> Int >>> An ambiguous scenario arrises when we wish to specialize initializer >>> functions: >>> >>> struct Foo<T: RawRepresentable where T.RawValue == String> { >>> let storage: T >>> >>> init<U: CustomStringConvertible>(_ value: U) { >>> storage = T(rawValue: value.description)! >>> } >>> } >>> >>> enum Bar: String, CustomStringConvertible { >>> case foobar = "foo" >>> >>> var description: String { >>> return self.rawValue >>> } >>> } >>> >>> let a = Foo<Bar>(Bar.foobar) >>> Does this specialization specialize the struct's or the initializer's >>> generic type? The proposal solves this ambiguity by requiring initializer >>> generic type specialization to use the init syntax: >>> >>> let a = Foo<Bar>.init<Bar>(Bar.foobar) >>> >>> <https://github.com/hartbit/swift-evolution/tree/allow-explicit-types-generic-functions#detailed-design>Detailed >>> Design >>> >>> Function calls are fairly straight forward and have their grammar modified >>> as follows: >>> >>> function-call-expression → postfix-expression generic-argument-clauseopt >>> parenthesized-expression >>> >>> function-call-expression → postfix-expression generic-argument-clauseopt >>> parenthesized-expressionopt trailing-closure >>> >>> To allow initializers to be called with explicit specialization, we need to >>> use the Initializer Expression. Its grammar is modified to: >>> >>> initializer-expression → postfix-expression . init >>> generic-argument-clauseopt >>> >>> initializer-expression → postfix-expression . init >>> generic-argument-clauseopt ( argument-names ) >>> >>> >>> <https://github.com/hartbit/swift-evolution/tree/allow-explicit-types-generic-functions#impact-on-existing-code>Impact >>> on Existing Code >>> >>> This proposal is purely additive and will have no impact on existing code. >>> >>> >>> <https://github.com/hartbit/swift-evolution/tree/allow-explicit-types-generic-functions#alternatives-considered>Alternatives >>> Considered >>> >>> Not adopting this proposal for Swift. >>> >>> _______________________________________________ >>> 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] https://lists.swift.org/mailman/listinfo/swift-evolution
