What I would like is a way to specialize a generic function in a block of code: 
(Strawman syntax)

        if T is Int.self {
                //In this block of code T == Int
        }

It seems to me that the compiler might even be able to optimize this without a 
branch.  If there is a return in the block, then it might even be able to throw 
away all the code after it for the Int version of the function.

Here is some actual (super ugly) code I wrote today.  I am unhappy with it and 
looking to remove or improve it, but it is the best I can figure out at the 
moment:

public static func operation<T>(symbol:String, type:T.Type)->((T,T)->T)?{
        if T.self == Int.self {
            var op:((Int,Int)->Int)? = nil
            switch symbol {
            case "+": op = (+)
            case "-": op = (-)
            case "*","x","•": op = (*)
            case "/","÷": op = (/)
            default: break
            }
            if op != nil {
                return op as! ((T,T)->T)?
            }
        }
// Function continues...

All this function does is take a string with a mathematical symbol in it and 
return an operation associated with that symbol/type (if it exists).  In 
addition to the built in ones here, the user is able to register custom symbols 
and operations (the machinery for that is further down and less ugly).

Notice that I need to cast the operation back to (T,T)->T because it doesn’t 
know that T is an Int here. It has an error saying the cast always fails, but 
that isn’t true.

Ideally, I would be able to check if T is Numeric and then just return the 
operator.  I have to do a bunch of extra work here to disambiguate for the 
compiler. It needs me to call out specific types (like Int) individually and 
then cast them back to T.

What I would like to do:

public static func operation<T>(symbol:String, type:T.Type)->((T,T)->T)?{
        if T.self is Numeric {
            switch symbol {
            case "+": return (+)
            case "-": return (-)
            case "*","x","•": return (*)
            case "/","÷": return (/)
            default: break
            }
        }
// Function continues…

or at least:

public static func operation<T>(symbol:String, type:T.Type)->((T,T)->T)?{
        if T.self is Int {
            switch symbol {
            case "+": return (+)
            case "-": return (-)
            case "*","x","•": return (*)
            case "/","÷": return (/)
            default: break
            }
        }
// Function continues...

Is it something that could be possible in a future version of Swift?  or am I 
missing something obvious that is much better than this?

Thanks,
Jon

> On Feb 28, 2017, at 2:15 PM, Douglas Gregor via swift-evolution 
> <[email protected]> wrote:
> 
>> 
>> On Feb 28, 2017, at 2:00 PM, David Hart <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> 
>>> On 28 Feb 2017, at 22:39, Douglas Gregor via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>> 
>>>> On Feb 27, 2017, at 11:21 PM, Nicolas Fezans via swift-evolution 
>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>> 
>>>> +1
>>>> I would also welcome to be able to use "or" and "and" logical operators 
>>>> (not only the not operator) on these constraints.
>>> 
>>> You already have “and’ constraints: it’s what you get out of the 
>>> comma-separated list of constraints in a where clause, or the “&” 
>>> composition syntax.
>>> 
>>>> I have sometimes generic functions whose code is identical but is written 
>>>> twice: first with 'where T=P1' and then with 'where T=P2', being able to 
>>>> write for instance 'where T=(P1 or P2)' would be very handy IMO.
>>>> One could often argue that additional protocols and extensions could be 
>>>> defined as a workaround to the situation I just mentioned but it seems 
>>>> often a bit of an overkill to me when you only have a couple of functions 
>>>> with that combination of requirements.
>>> 
>>> “Or” constraints are a nonstarter for me, because you can’t meaningfully 
>>> type-check a generic function that uses “or” constraints: the problem goes 
>>> exponential in the number of “or” constraints and the meaning of the 
>>> function can change considerably depending on which set of terms are 
>>> satisfied—in which case you have ambiguities again!
>>> 
>>> Whenever this topic comes up, I like to point people at:
>>> 
>>>     http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2161.pdf 
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2161.pdf>
>> Should we also follow Recommendation #2 and revert the P1 & P2 change to 
>> return to Any<P1, P2> :) Half-joking.
> 
> That line of argument got thoroughly shot down in the core team meeting when 
> we discussed the introduction of the & operator for types.
> 
>       - 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]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to