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) 
> <swift-callion...@callionica.com> 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 
>> <swift-evolution@swift.org> 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
>> Author: David Hart, Douglas Gregor
>> Status: TBD
>> Review manager: TBD
>> Introduction
>> 
>> This proposal allows bypassing the type inference engine and explicitly 
>> specializing type arguments of generic functions. 
>> 
>> 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)
>> Detailed Design
>> 
>> Function calls are fairly straight forward and have their grammar modified 
>> as follows:
>> 
>> function-call-expression → postfix-expression­ generic-argument-clause­opt 
>> parenthesized-expression
>> 
>> function-call-expression → postfix-expression generic-argument-clause­opt 
>> ­parenthesized-expression­opt ­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-clause­opt
>> 
>> initializer-expression → postfix-expression­ . ­init­ 
>> generic-argument-clause­opt ( ­argument-names­ )
>> 
>> Impact on Existing Code
>> 
>> This proposal is purely additive and will have no impact on existing code.
>> 
>> Alternatives Considered
>> 
>> Not adopting this proposal for Swift.
>> 
>> _______________________________________________
>> 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