> On Jun 9, 2017, at 3:16 PM, Tony Allevato <tony.allev...@gmail.com> wrote: > > Makes sense. I guess from an implementation point of view, the compiler only > needs to be able to see the signatures of the members to synthesize the calls > to them. My thinking was that conforming the original type would remove the > need for the compiler to verify separately that the members exist on the type > (because of it conforms, they must, so you get it for free), but I suppose in > this case the compiler would just do a separate validation pass.
Yeah, conformance could be used as a shortcut when it exists but requiring it is an unnecessary limitation that reduces flexibility and actually prevents some uses altogether. > > I'm really looking forward to reading your draft! > On Fri, Jun 9, 2017 at 12:58 PM Matthew Johnson <matt...@anandabits.com > <mailto:matt...@anandabits.com>> wrote: >> On Jun 9, 2017, at 2:53 PM, Tony Allevato <tony.allev...@gmail.com >> <mailto:tony.allev...@gmail.com>> wrote: >> >> +1 to this. My ideal imagining of this behavior is to: >> >> 1) Define a protocol containing the precise operations you want to support >> via forwarding. >> 2) Internally/fileprivately extend the original type to conform to this >> protocol. >> 3) In your new type, tell it to forward protocol members for a particular >> property (the underlying String, or whatever) and the compiler will >> synthesize the protocol member stubs on the new type. >> >> There are definitely finer details to be worked out but that's a rough >> sketch of how I've been imagining it could work. Nice advantages include (1) >> if there already exists a protocol that defines the exact operations you >> want to forward, you can skip step 2, and (2) it's explicit/opt-in synthesis >> where you have to provide the members to forward (this is expected, at a >> minimum), but you don't have to write all the boilerplate implementations. > > I have a mostly finished second draft of a protocol-oriented forwarding > proposal which is pretty similar to what you describe here. The most > important difference is that while protocols are used to perform forwarding > neither type is required to actually conform to the protocol. > > That turns out to be pretty important when you think about edge cases. > Sometimes you don’t actually want the forwardee to conform (that’s probably > why you said internal / fileprivate). Sometimes you also don’t want the > forwarder to conform. IIRC, there are also cases where it cannot conform (I > would have to dig up the proposal to recall the details). > >> >> >> On Fri, Jun 9, 2017 at 12:47 PM Matthew Johnson via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>> On Jun 9, 2017, at 2:39 PM, Xiaodi Wu <xiaodi...@gmail.com >>> <mailto:xiaodi...@gmail.com>> wrote: >>> >>> Interesting. So you’d want `newtype Foo = String` to start off with no >>> members on Foo? >> >> Yeah. Previous discussions of newtype have usually led to discussion of >> ways to forward using a protocol-oriented approach. Nothing has gotten too >> far, but it usually comes up that suppressing undesired members is important. >> >> It is also important to have some way to distinguish between members with a >> parameter of the underlying type from members that should be treated by >> newtype as Self parameters. The mechanism we have for doing that in Swift >> happens to be a protocol. >> >>> On Fri, Jun 9, 2017 at 15:18 Matthew Johnson <matt...@anandabits.com >>> <mailto:matt...@anandabits.com>> wrote: >>>> On Jun 9, 2017, at 12:09 PM, Xiaodi Wu via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>> >>>> On Fri, Jun 9, 2017 at 12:44 Robert Bennett via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>> Somewhat related to this, shouldn’t it be possible to sub-struct a struct >>>> as long as you only add functions and computed properties (i.e., no stored >>>> properties)? Traditionally structs cannot be subtyped because their size >>>> must be known at compile time. I don’t know the implementation details of >>>> where functions and computed properties live, but something tells me they >>>> belong to the type and not the object (although I’ve never really made the >>>> effort to sit down and fully understand Swift’s type model), in which case >>>> adding them to a struct’s definition would not change the size of the >>>> object on the stack. Thus it should be possible to make custom substructs >>>> of String that add additional functionality but no new stored properties. >>>> Thoughts? >>>> >>>> Value subtyping is a large subject and, IIUC, newtype would be a subset of >>>> that topic. Unlikely to be in scope for Swift 5, though, but that’s up to >>>> the core team. >>> >>> I see newtype as being more related to forwarding than subtyping. Usually >>> you want to hide significant parts of the interface to the wrapped type. >>> >>>> >>>> >>>> On Jun 9, 2017, at 12:12 PM, Jacob Williams via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>> >>>>>> On Jun 9, 2017, at 9:53 AM, Charlie Monroe <char...@charliemonroe.net >>>>>> <mailto:char...@charliemonroe.net>> wrote: >>>>>> >>>>>> -1 - this would disallow e.g. to share UI code between iOS and macOS: >>>>>> >>>>>> #if os(iOS) >>>>>> typealias XUView = UIView >>>>>> #else >>>>>> typealias XUView = NSView >>>>>> #endif >>>>>> >>>>>> extension XUView { >>>>>> ... >>>>>> } >>>>> >>>>> I really don’t see how this disallows code sharing between the two >>>>> systems? Could you explain further? Based on my understanding of the >>>>> pitch, this is valid code still. (Although I do like the suggestion of a >>>>> new keyword rather than just limiting type alias). >>>>> >>>>> Even if your example was invalid, you could also just do something like >>>>> this: >>>>> >>>>> #if os(iOS) >>>>> typealias XUView = UIView >>>>> extension XUView { >>>>> //extension code here >>>>> } >>>>> #if os(macOS) >>>>> typealias XUView = UIView >>>>> extension XUView { >>>>> // extension code here >>>>> } >>>>> #endif >>>>> >>>>> While not as pretty, still just as effective if you have to deal with >>>>> different types based on the system being compiled for and you could >>>>> easily still make the type alias extensions for each type work the same. >>>>> >>>>>> On Jun 9, 2017, at 9:53 AM, Charlie Monroe <char...@charliemonroe.net >>>>>> <mailto:char...@charliemonroe.net>> wrote: >>>>>> >>>>>> -1 - this would disallow e.g. to share UI code between iOS and macOS: >>>>>> >>>>>> #if os(iOS) >>>>>> typealias XUView = UIView >>>>>> #else >>>>>> typealias XUView = NSView >>>>>> #endif >>>>>> >>>>>> extension XUView { >>>>>> ... >>>>>> } >>>>>> >>>>>> or with any similar compatibility typealiases. >>>>>> >>>>>>> On Jun 9, 2017, at 5:38 PM, Jacob Williams via swift-evolution >>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>>>>> >>>>>>> +1 from me. >>>>>>> >>>>>>> There have been times I’ve wanted to subclass an object (such as >>>>>>> String) but since it is a non-class, non-protocol type you can only >>>>>>> extend Strings existing functionality which adds that same >>>>>>> functionality to Strings everywhere. It would be nice if we could >>>>>>> either extend type aliases (and only the type alias), or if it were >>>>>>> possible to inherit from structs so that we could create a custom >>>>>>> string type like so: >>>>>>> >>>>>>> struct HeaderKey: String { >>>>>>> static var lastModified: String { return “Last-Modified” } >>>>>>> static var host: String { return “Host” } >>>>>>> } >>>>>>> >>>>>>> I realize that struct inheritance is far less likely, since that >>>>>>> defeats one of the main pieces of what makes a struct a struct. So I’m >>>>>>> all for this proposal of allowing type aliases to be extended as though >>>>>>> they were their own struct/class. >>>>>>> >>>>>>> Unfortunately, I’m not sure how feasible this kind of functionality >>>>>>> would actually be, but if it’s possible then I’m in favor of >>>>>>> implementing it. >>>>>>> >>>>>>>> On Jun 8, 2017, at 10:14 PM, Yvo van Beek via swift-evolution >>>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>>>>>> >>>>>>>> Typealiases can greatly reduce the complexity of code. But I think one >>>>>>>> change in how the compiler handles them could make them even more >>>>>>>> powerful. >>>>>>>> >>>>>>>> Let's say I'm creating a web server framework and I've created a >>>>>>>> simple dictionary to store HTTP headers (I know that headers are more >>>>>>>> complex than that, but as an example). I could write something like >>>>>>>> this: >>>>>>>> >>>>>>>> typealias HeaderKey = String >>>>>>>> >>>>>>>> var headers = [HeaderKey: String]() >>>>>>>> headers["Host"] = "domain.com <http://domain.com/>" >>>>>>>> >>>>>>>> Now I can define a couple of default headers like this: >>>>>>>> >>>>>>>> extension HeaderKey { >>>>>>>> static var lastModified: String { return "Last-Modified" } >>>>>>>> static var host: String { return "Host" } >>>>>>>> } >>>>>>>> >>>>>>>> After that I can do this: >>>>>>>> >>>>>>>> var headers = [HeaderKey: String]() >>>>>>>> headers[.host] = "domain.com <http://domain.com/>" >>>>>>>> headers[.lastModified] = "some date" >>>>>>>> headers["X-MyHeader"] = "This still works too" >>>>>>>> >>>>>>>> But unfortunately the extension is also applied to normal strings: >>>>>>>> >>>>>>>> var normalString: String = .host >>>>>>>> >>>>>>>> Perhaps it would be better if the extension would only apply to the >>>>>>>> parts of my code where I use the HeaderKey typealias and not to all >>>>>>>> Strings. This could be a great tool to specialize classes by creating >>>>>>>> a typealias and adding functionality to it. Another example I can >>>>>>>> think of is typealiases for dictionaries or arrays with added business >>>>>>>> logic through extensions (especially since you can't inherit from >>>>>>>> structs). >>>>>>>> >>>>>>>> If you want to create an extension that adds functionality to all >>>>>>>> Strings you could have created an extension for String instead of >>>>>>>> HeaderKey. >>>>>>>> >>>>>>>> Please let me know what you think. I'm not sure how complex this >>>>>>>> change would be. >>>>>>>> I could write a proposal if you're interested. >>>>>>>> >>>>>>>> Kind regards, >>>>>>>> Yvo >>>>>>>> _______________________________________________ >>>>>>>> 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 <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 <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 <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 <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 <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