protocol Bondable {
    associatedtype Key
    associatedtype Value

    static func new() -> Self

    func value(forKey key: Key) -> Value?

    mutating func updateValue(_ value: Value?, forKey key: Key)
}

extension Dictionary: Bondable {
    static func new() -> Dictionary<Key, Value> {
        return Dictionary<Key, Value>()
    }

    func value(forKey key: Key) -> Value? {
        return self[key]
    }

    mutating func updateValue(_ value: Value?, forKey key: Key) {
        self[key] = value
    }
}

struct Bridge<A, B> {
    struct Getter {
        var transform: ((B) -> A?)
    }

    struct Setter {
        var transform: ((A) -> B?)
    }

    var get: Getter
    var set: Setter
}

protocol Bonding {
    associatedtype Dictionary: Bondable
    associatedtype Value

    var key: Dictionary.Key { get set }

    var bridge: Bridge<Value, Dictionary.Value> { get set }

    func value(from aDictionary: Dictionary, using set: Bridge<Value, 
Dictionary.Value>.Getter) -> Value?

    func addValue(_ value: Value, to aDictionary: inout Dictionary, using get: 
Bridge<Value, Dictionary.Value>.Setter)
}

extension Bonding {

    func value(from aDictionary: Dictionary, using get: Bridge<Value, 
Dictionary.Value>.Getter) -> Value? {
        if let value = aDictionary.value(forKey: key) {
            return get.transform(value)
        } else {
            return nil

        }
    }

    func addValue(_ value: Value, to aDictionary: inout Dictionary, using set: 
Bridge<Value, Dictionary.Value>.Setter) {
        aDictionary.updateValue(set.transform(value), forKey: key)
    }
}

struct ComplexBond<__Dictionary: Bondable, __Value>: Bonding {
    typealias Dictionary = __Dictionary
    typealias Value = __Value

    var key: __Dictionary.Key

    var bridge: Bridge<__Value, __Dictionary.Value>
}

The above is an example implementation of the `Bonding` protocol, where the 
preexisting names of the associated types, `Dictionary` and `Value`, are 
already appropriately named. It would be great if I could just add a simple 
keyword prefixing the `typealias` keyword which would enable the inferencing 
behavior.

On Jun 23, 2017, 8:36 PM -0400, Xiaodi Wu <[email protected]>, wrote:
> Yes, examples will be helpful.
>
>
> > On Fri, Jun 23, 2017 at 19:28 David Moore via swift-evolution 
> > <[email protected]> wrote:
> > > I do indeed have quite a few real examples of this, such prompted me to 
> > > bring this up. I think this could be done without any impact to existing 
> > > code, but it would require some type of keyword. Take the following as a 
> > > possible prototype.
> > >
> > > protocol Foo {
> > >     associatedtype T
> > > }
> > >
> > > struct Bar<T> : Foo {
> > >     keyword typealias T // Or really any other syntactical implementation.
> > > }
> > >
> > > With an opt-in method we could implement this without affecting existing 
> > > code, thereby making this more viable. I will send some examples later.
> > >
> > > On Jun 23, 2017, at 6:52 PM, Xiaodi Wu <[email protected]> wrote:
> > >
> > > > There could be source-breaking implications for such a feature, 
> > > > especially with retroactive conformance. Therefore, I think this could 
> > > > be very tricky and I'd want to be convinced that the benefits are very 
> > > > great to risk such a disturbance. Here, I think the problem is rather 
> > > > mild, and here's why:
> > > >
> > > > It is true that, in your example specifically, renaming T to U is the 
> > > > only solution (that I know of, anyway). However, for any "serious" 
> > > > protocol P, there's likely to be a required property of type P.T, or a 
> > > > function that takes an argument of type P.T or returns a value of type 
> > > > P.T. Therefore, implementing that requirement in Bar with a 
> > > > corresponding property/argument/return value of type Bar.T would 
> > > > generally do the trick.
> > > >
> > > > Have you got any real-world examples where you're running into this 
> > > > issue?
> > > >
> > > > > On Fri, Jun 23, 2017 at 17:03 David Moore via swift-evolution 
> > > > > <[email protected]> wrote:
> > > > > > Hello Swift Evolution,
> > > > > >
> > > > > > This may have already been discussed before, but I just came across 
> > > > > > a bothersome language aspect which reminded me to propose a 
> > > > > > solution. Currently, if we want to add generics to a protocol the 
> > > > > > only way to do so is with associated types. I am quite fine with 
> > > > > > the current approach with respect to those semantics.
> > > > > >
> > > > > > There is, however, a weakness that is built in with using 
> > > > > > associated types. That weakness is the lack of associated type and 
> > > > > > generic inference. To be more clear about what I mean, take the 
> > > > > > following as an example.
> > > > > >
> > > > > > protocol Foo {
> > > > > >     associatedtype T
> > > > > > }
> > > > > >
> > > > > > The foregoing protocol is quite basic, but uses an associated type 
> > > > > > with the name “T.” Giving the associated type that name will 
> > > > > > illustrate the dilemma encountered later on down the pipeline.
> > > > > >
> > > > > > struct Bar<T> : Foo {
> > > > > >     // What am I supposed to do? The name is used for both the 
> > > > > > generic and the type alias Foo needs for conformance.
> > > > > >     typealias T = T // Error!
> > > > > > }
> > > > > >
> > > > > > The above illustrates a situation where we want to connect the 
> > > > > > generic, which is supposedly named appropriately, and the 
> > > > > > protocol’s associated type. There is no elegant solution for this 
> > > > > > at the moment. All I could do is the following.
> > > > > >
> > > > > > struct Bar<U> : Foo {
> > > > > >     typealias T = U // Not nearly as readable.
> > > > > > }
> > > > > >
> > > > > > Now, there may be a few ways to go about adding support for generic 
> > > > > > inference. The compiler as it is already does some awesome 
> > > > > > inference get when it comes to generics, so why not take it a step 
> > > > > > further? I propose the introduction of a keyword, or anything else 
> > > > > > that could work, to specify explicitly what a given type alias 
> > > > > > declaration would do when it comes to inferencing. Requiring a 
> > > > > > keyword would ensure source compatibility remains intact, and it 
> > > > > > would also make the code more readable.
> > > > > >
> > > > > > I don’t know if this would be something that people could find 
> > > > > > useful, but I surely would. The implicit mapping of an associated 
> > > > > > type and a given generic by their names, would be a natural 
> > > > > > development.
> > > > > >
> > > > > > Let me know if this is just useless, or if could be a potential 
> > > > > > feature.
> > > > > >
> > > > > > Thank you,
> > > > > > David Moore
> > > > > > _______________________________________________
> > > > > > 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
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to