> On Jun 23, 2016, at 1:30 PM, Slava Pestov <spes...@apple.com> wrote:
> 
> 
>> On Jun 23, 2016, at 1:27 PM, Xiaodi Wu <xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>> 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.

This should make it clearer:

struct GenericBox<Contents> {
  let contents: Contents

  func transform<Result>(f: (Contents) -> Result) -> GenericBox<Result> {
    // If you change this to just ‘GenericBox(contents: …)’, it does not type 
check
    return GenericBox<Result>(contents: f(contents))
  }
}

func transform<Contents, Result>(box: GenericBox<Contents>,
                  f: (Contents) -> Result) -> GenericBox<Result> {
  // But this is totally fine!
  return GenericBox(contents: f(box.contents))
}

I suspect most people do not expect the first case to fail, and it is not 
immediately obvious why it fails when the second example type checks.

> 
> 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 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <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