[swift-evolution] [Pitch] Simpler interpretation of a reference to a generic type with no arguments

Pyry Jahkola pyry.jahkola at iki.fi
Tue Oct 11 15:58:29 CDT 2016


I was reminded of this proposal which seems like an obvious win in clarity. Still planning to submit it, Slava?

— Pyry

> On 28 Jun 2016, at 21:13, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
> 
> on Thu Jun 23 2016, Slava Pestov <swift-evolution at 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.
> 
> SGTM.  I've always found this shorthand to be somewhat surprising,
> including in C++ where (IIUC) it originated.
> 
> 
> -- 
> Dave



More information about the swift-evolution mailing list