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

Xiaodi Wu xiaodi.wu at gmail.com
Thu Jun 23 15:39:29 CDT 2016


Good to know. I absolutely agree that the gains to be had here wouldn't be
worth a one-off hack.
On Thu, Jun 23, 2016 at 15:36 Slava Pestov <spestov at apple.com> wrote:

> On Jun 23, 2016, at 1:34 PM, Xiaodi Wu <xiaodi.wu at gmail.com> 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 <spestov at apple.com> wrote:
>
>> On Jun 23, 2016, at 1:27 PM, Xiaodi Wu <xiaodi.wu at 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.
>>
>> 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 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.
>>>
>>> <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 at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160623/7bb9ed8e/attachment.html>


More information about the swift-evolution mailing list