Cool--no opposition here! On Thu, Jun 23, 2016 at 15:43 Slava Pestov <[email protected]> wrote:
> 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]> wrote: > >> On Jun 23, 2016, at 1:34 PM, Xiaodi Wu <[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]> wrote: >> >>> On Jun 23, 2016, at 1:27 PM, Xiaodi Wu <[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]> 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] >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>> >>> >>> >>
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
