[swift-evolution] 'T != Type' in where clause

Douglas Gregor dgregor at apple.com
Fri Mar 3 01:09:59 CST 2017


> On Mar 1, 2017, at 12:59 PM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
> on Wed Mar 01 2017, Douglas Gregor <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 
>>> On Mar 1, 2017, at 1:55 AM, Jonathan Hull <jhull at gbis.com> wrote:
>>> 
>>> 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.
>> 
>> We’ve been calling this “type refinement”. Essentially, within some
>> lexical context (the “if” here) we can assert additional properties on
>> a type or one specific (constant) values and take advantage of those
>> properties, as you’ve done with T == Int.
>> 
>> It’s a plausible language feature, and could be useful. There’s
>> certainly some precedent for it: C++17 adds something similar with
>> “constexpr if”, albeit in their non-separately-type-checked template
>> instantiation model.
>> 
>> It’s a nontrivial language feature that’s well out of scope for Swift 4.
> 
> Huh?  This totally works:
> 
>  extension Optional {                                                                                                                            
>    func goo() -> Int { 
>      return Wrapped.self is Int.Type ? 1 : 0
>    }                                                                                    
>  }
> 
>  func rue() -> Int {
>    return (nil as Bool?).goo() + (nil as Int?).goo()
>  }
> 
>  /* rue optimizes down to:
> 
>          .private_extern	__TF1x3rueFT_Si
>          .globl	__TF1x3rueFT_Si
>          .p2align	4, 0x90
>  __TF1x3rueFT_Si:
>          pushq	%rbp
>          movq	%rsp, %rbp
>          movl	$1, %eax
>          popq	%rbp
>          retq
>  */
> 
>  print(rue())
> 
> What am I missing?

In a context where “T == Int”, I’d expect to be able to write code that depends on that assumption:

func f<T>(a1: [T]) {
  var a2 = a1
  if where T == Int { /* crazy syntax, I know */
    a2.append(1) // fine, because T == Int
  }
}

	- Doug


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170302/53e0efd9/attachment.html>


More information about the swift-evolution mailing list