> 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