> On Jun 23, 2016, at 1:39 PM, Xiaodi Wu <[email protected]> wrote:
> 
> Good to know. I absolutely agree that the gains to be had here wouldn't be 
> worth a one-off hack.

If people are strongly (or even mildly) opposed to removing this rule, we can 
give some thought to a more general solution. I don’t feel very strongly about 
this proposal one way or another, it’s just a bit of ugly code in 
TypeCheckType.cpp that would be nice to remove, and a developer on Twitter 
recently noticed this behavior and found it surprising.

> On Thu, Jun 23, 2016 at 15:36 Slava Pestov <[email protected] 
> <mailto:[email protected]>> wrote:
>> On Jun 23, 2016, at 1:34 PM, Xiaodi Wu <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> Sorry, it's I who is saying things all wrong. I meant to ask, is it feasible 
>> to keep both behaviors but have #2 "win" over #1, instead of getting rid of 
>> behavior #1 entirely?
> 
> I suspect there might be some way, but I think it would have to be some kind 
> of one-off hack, which is not in line with our long-term goal of making the 
> type checker more maintainable and correct ‘by construction’.
> 
>> 
>> On Thu, Jun 23, 2016 at 15:30 Slava Pestov <[email protected] 
>> <mailto:[email protected]>> wrote:
>>> On Jun 23, 2016, at 1:27 PM, Xiaodi Wu <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>> When you mention the difficulty of an alternative, is that to say that it's 
>>> not feasible for the GenericBox in the last example to be resolved as 
>>> GenericBox<T>? From an end-user point of view, that seems to be the most 
>>> sensible behavior.
>> 
>> With my proposed change, GenericBox would be resolved as GenericBox<T> in 
>> the last example. Right now it fails to type check.
>> 
>> Here is an example that works right now, but would not work with my proposed 
>> change:
>> 
>> struct GenericBox<Contents> {
>>      // Currently Swift resolves this as ‘GenericBox<Contents>’
>>      // With the new rule, we cannot infer the parameter, because there’s no 
>> expression to infer it from
>>      func combine(other: GenericBox) {
>>              …
>>      }
>> }
>> 
>> Basically the meaning of ‘GenericBox’ right now depends on whether it 
>> appears inside its own definition or extension thereof, or not. The behavior 
>> when it appears elsewhere is more general — we infer the parameters from the 
>> surrounding expression, instead of assuming they’re equal to the context 
>> parameters.
>> 
>> This is a subtle change — definitely let me know if I’m not explaining it 
>> well.
>> 
>> Slava
>> 
>>> On Thu, Jun 23, 2016 at 15:14 Slava Pestov via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> Simpler interpretation of a reference to a generic type with no arguments
>>> 
>>> Proposal: SE-9999 
>>> <https://github.com/slavapestov/swift-evolution/blob/silly-proposals/proposals/9999-simplify-unbound-generic-type.md>
>>> Author: Slava Pestov <https://github.com/slavapestov>
>>> Status: Awaiting review
>>> Review manager: TBD
>>>  
>>> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#introduction>Introduction
>>> 
>>> This proposal cleans up the semantics of a reference to a generic type when 
>>> no generic arguments are applied.
>>> 
>>> Swift-evolution thread: Discussion thread topic for that proposal 
>>> <http://news.gmane.org/gmane.comp.lang.swift.evolution>
>>>  
>>> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#motivation>Motivation
>>> 
>>> Right now, we allow a generic type to be referenced with no generic 
>>> arguments applied in a handful of special cases. The two primary rules here 
>>> are the following:
>>> 
>>> If the scope from which the reference is made is nested inside the 
>>> definition of the type or an extension thereof, omitting generic arguments 
>>> just means to implicitly apply the arguments from context.
>>> 
>>> For example,
>>> 
>>> struct GenericBox<Contents> {
>>>   let contents: Contents
>>> 
>>>   // Equivalent to: func clone() -> GenericBox<Contents>
>>>   func clone() -> GenericBox {
>>>     return GenericBox(contents: contents)
>>>   }
>>> }
>>> 
>>> extension GenericBox {
>>>   func print() {
>>>     // Equivalent to: let cloned: GenericBox<Contents>
>>>     let cloned: GenericBox = clone()
>>>     print(cloned.contents)
>>>   }
>>> }
>>> If the type is referenced from an unrelated scope, we attempt to infer the 
>>> generic parameters.
>>> 
>>> For example,
>>> 
>>> func makeABox() -> GenericBox<Int> {
>>>   // Equivalent to: GenericBox<Int>(contents: 123)
>>>   return GenericBox(contents: 123)
>>> }
>>> The problem appears when the user expects the second behavior, but instead 
>>> encounters the first. For example, the following does not type check:
>>> 
>>> extension GenericBox {
>>> 
>>>   func transform<T>(f: Contents -> T) -> GenericBox<T> {
>>>     // We resolve 'GenericBox' as 'GenericBox<Contents>', rather than
>>>     // inferring the type parameter
>>>     return GenericBox(contents: f(contents))
>>>   }
>>> }
>>>  
>>> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#proposed-solution>Proposed
>>>  solution
>>> 
>>> The proposed solution is to remove the first rule altogether. If the 
>>> generic parameters cannot be inferred from context, they must be specified 
>>> explicitly with the usual Type<Args...> syntax.
>>> 
>>>  
>>> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#detailed-design>Detailed
>>>  design
>>> 
>>> This really just involves removing an existing piece of logic from the type 
>>> resolver code.
>>> 
>>>  
>>> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#impact-on-existing-code>Impact
>>>  on existing code
>>> 
>>> This will have a small impact on existing code that uses a pattern similar 
>>> to the above.
>>> 
>>>  
>>> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#alternatives-considered>Alternatives
>>>  considered
>>> 
>>>  
>>> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#status-quo>Status
>>>  quo
>>> 
>>> We could keep the current behavior, but one can argue it is not very 
>>> useful, and adds a special case where one is not needed.
>>> 
>>>  
>>> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#more-complex-inference-of-generic-parameters>More
>>>  complex inference of generic parameters
>>> 
>>> We could attempt to unify the two rules for resolving a reference to a 
>>> generic type with no arguments, however this presents theoretical 
>>> difficulties with our constraint solver design. Even if it were easy to 
>>> implement, it would increase type checking type by creating new 
>>> possibilities to consider, with very little actual benefit.
>>> _______________________________________________
>>> 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