Default implementation of protocols


(Jon Hull) #1

Have we considered allowing a struct/class/enum to have the same name as a protocol as long as it conforms to the protocol? Type declarations would have to always mean the protocol (which includes the concrete type as well). Static functions would always apply to the concrete type.

Seems like a good way to support having a default implementation of a protocol. I am always running into the awkward naming issues around this...

  protocol X {
    //yada yada
  }

  struct X { //Implicitly adheres to protocol X (because it must)
    init(){…}
  }

  let myVar:X //This refers to the protocol
  let otherVar = X() //This makes the struct

If we do need to be able to spell the concrete type for other uses, we could probably do something like: ‘concrete(X)’ which isn’t pretty, but is there for the rare times it is needed for utility. I can’t think of any reason except making an array of the concrete type.

I am guessing there is a subtle technical reason this won’t work, but I wanted to mention it now just in case it is possible. Seems like it could have a large (simplifying) effect on the namespace of the standard library.

Thanks,
Jon


(Xiaodi Wu) #2

This would get very confusing, as it would be impossible for a class to
distinguish conforming to protocol X vs. inheriting from base class X, or
else we would have to change the spelling for that as well. Moreover, you
would have no way of distinguishing the existential X from the struct X. I
see nothing wrong with the clarity afforded by naming the distinct things
`FooProtocol` and `Foo`, and I disagree that there's anything "simplifying"
about naming two different things with one name.

···

On Mon, Jan 23, 2017 at 6:13 PM, Jonathan Hull via swift-evolution < swift-evolution@swift.org> wrote:

Have we considered allowing a struct/class/enum to have the same name as a
protocol as long as it conforms to the protocol? Type declarations would
have to always mean the protocol (which includes the concrete type as
well). Static functions would always apply to the concrete type.

Seems like a good way to support having a default implementation of a
protocol. I am always running into the awkward naming issues around this...

        protocol X {
                //yada yada
        }

        struct X { //Implicitly adheres to protocol X (because it must)
                init(){…}
        }

        let myVar:X //This refers to the protocol
        let otherVar = X() //This makes the struct

If we do need to be able to spell the concrete type for other uses, we
could probably do something like: ‘concrete(X)’ which isn’t pretty, but is
there for the rare times it is needed for utility. I can’t think of any
reason except making an array of the concrete type.

I am guessing there is a subtle technical reason this won’t work, but I
wanted to mention it now just in case it is possible. Seems like it could
have a large (simplifying) effect on the namespace of the standard library.

Thanks,
Jon
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Karl) #3

IMO, the way to do this is by nesting the struct inside the protocol (not possible yet). For example, the standard library contains EmptyCollection and CollectionOfOne. I think the way to express such things would be as: Collection.Empty<T> and Collection.One<T>.

Not promising anything about the stdlib interface itself, but in general I think these kind of canned conformances are ideal candidates for nesting. So in your case you might have X.Default (or something more meaningful).

- Karl

···

On 24 Jan 2017, at 01:13, Jonathan Hull via swift-evolution <swift-evolution@swift.org> wrote:

Have we considered allowing a struct/class/enum to have the same name as a protocol as long as it conforms to the protocol? Type declarations would have to always mean the protocol (which includes the concrete type as well). Static functions would always apply to the concrete type.

Seems like a good way to support having a default implementation of a protocol. I am always running into the awkward naming issues around this...

  protocol X {
    //yada yada
  }

  struct X { //Implicitly adheres to protocol X (because it must)
    init(){…}
  }

  let myVar:X //This refers to the protocol
  let otherVar = X() //This makes the struct

If we do need to be able to spell the concrete type for other uses, we could probably do something like: ‘concrete(X)’ which isn’t pretty, but is there for the rare times it is needed for utility. I can’t think of any reason except making an array of the concrete type.

I am guessing there is a subtle technical reason this won’t work, but I wanted to mention it now just in case it is possible. Seems like it could have a large (simplifying) effect on the namespace of the standard library.

Thanks,
Jon
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jon Hull) #4

I agree with your point on classes, so maybe just value types would be allowed to do it (I have only wanted it for structs myself). I think I answered your comment about distinguishing between existential and struct X if you re-read my original message.

Thanks,
Jon

···

On Jan 23, 2017, at 5:10 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

This would get very confusing, as it would be impossible for a class to distinguish conforming to protocol X vs. inheriting from base class X, or else we would have to change the spelling for that as well. Moreover, you would have no way of distinguishing the existential X from the struct X. I see nothing wrong with the clarity afforded by naming the distinct things `FooProtocol` and `Foo`, and I disagree that there's anything "simplifying" about naming two different things with one name.

On Mon, Jan 23, 2017 at 6:13 PM, Jonathan Hull via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Have we considered allowing a struct/class/enum to have the same name as a protocol as long as it conforms to the protocol? Type declarations would have to always mean the protocol (which includes the concrete type as well). Static functions would always apply to the concrete type.

Seems like a good way to support having a default implementation of a protocol. I am always running into the awkward naming issues around this...

        protocol X {
                //yada yada
        }

        struct X { //Implicitly adheres to protocol X (because it must)
                init(){…}
        }

        let myVar:X //This refers to the protocol
        let otherVar = X() //This makes the struct

If we do need to be able to spell the concrete type for other uses, we could probably do something like: ‘concrete(X)’ which isn’t pretty, but is there for the rare times it is needed for utility. I can’t think of any reason except making an array of the concrete type.

I am guessing there is a subtle technical reason this won’t work, but I wanted to mention it now just in case it is possible. Seems like it could have a large (simplifying) effect on the namespace of the standard library.

Thanks,
Jon
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jon Hull) #5

Ok, I could get behind that. Especially if we get factory initializers on protocols…

Thanks,
Jon

···

On Jan 23, 2017, at 5:57 PM, Karl Wagner <razielim@gmail.com> wrote:

On 24 Jan 2017, at 01:13, Jonathan Hull via swift-evolution <swift-evolution@swift.org> wrote:

Have we considered allowing a struct/class/enum to have the same name as a protocol as long as it conforms to the protocol? Type declarations would have to always mean the protocol (which includes the concrete type as well). Static functions would always apply to the concrete type.

Seems like a good way to support having a default implementation of a protocol. I am always running into the awkward naming issues around this...

  protocol X {
    //yada yada
  }

  struct X { //Implicitly adheres to protocol X (because it must)
    init(){…}
  }

  let myVar:X //This refers to the protocol
  let otherVar = X() //This makes the struct

If we do need to be able to spell the concrete type for other uses, we could probably do something like: ‘concrete(X)’ which isn’t pretty, but is there for the rare times it is needed for utility. I can’t think of any reason except making an array of the concrete type.

I am guessing there is a subtle technical reason this won’t work, but I wanted to mention it now just in case it is possible. Seems like it could have a large (simplifying) effect on the namespace of the standard library.

Thanks,
Jon
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

IMO, the way to do this is by nesting the struct inside the protocol (not possible yet). For example, the standard library contains EmptyCollection and CollectionOfOne. I think the way to express such things would be as: Collection.Empty<T> and Collection.One<T>.

Not promising anything about the stdlib interface itself, but in general I think these kind of canned conformances are ideal candidates for nesting. So in your case you might have X.Default (or something more meaningful).

- Karl


(Xiaodi Wu) #6

No, I don't think so. How would you declare a variable of type X, meaning
the protocol?

···

On Mon, Jan 23, 2017 at 19:49 Jonathan Hull <jhull@gbis.com> wrote:

I agree with your point on classes, so maybe just value types would be
allowed to do it (I have only wanted it for structs myself). I think I
answered your comment about distinguishing between existential and struct X
if you re-read my original message.

Thanks,
Jon

On Jan 23, 2017, at 5:10 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

This would get very confusing, as it would be impossible for a class to
distinguish conforming to protocol X vs. inheriting from base class X, or
else we would have to change the spelling for that as well. Moreover, you
would have no way of distinguishing the existential X from the struct X. I
see nothing wrong with the clarity afforded by naming the distinct things
`FooProtocol` and `Foo`, and I disagree that there's anything "simplifying"
about naming two different things with one name.

On Mon, Jan 23, 2017 at 6:13 PM, Jonathan Hull via swift-evolution < > swift-evolution@swift.org> wrote:

Have we considered allowing a struct/class/enum to have the same name as a
protocol as long as it conforms to the protocol? Type declarations would
have to always mean the protocol (which includes the concrete type as
well). Static functions would always apply to the concrete type.

Seems like a good way to support having a default implementation of a
protocol. I am always running into the awkward naming issues around this...

        protocol X {
                //yada yada
        }

        struct X { //Implicitly adheres to protocol X (because it must)
                init(){…}
        }

        let myVar:X //This refers to the protocol
        let otherVar = X() //This makes the struct

If we do need to be able to spell the concrete type for other uses, we
could probably do something like: ‘concrete(X)’ which isn’t pretty, but is
there for the rare times it is needed for utility. I can’t think of any
reason except making an array of the concrete type.

I am guessing there is a subtle technical reason this won’t work, but I
wanted to mention it now just in case it is possible. Seems like it could
have a large (simplifying) effect on the namespace of the standard library.

Thanks,
Jon
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Xiaodi Wu) #7

Moreover, how would you extend the protocol?

···

On Mon, Jan 23, 2017 at 19:51 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

No, I don't think so. How would you declare a variable of type X, meaning
the protocol?
On Mon, Jan 23, 2017 at 19:49 Jonathan Hull <jhull@gbis.com> wrote:

I agree with your point on classes, so maybe just value types would be
allowed to do it (I have only wanted it for structs myself). I think I
answered your comment about distinguishing between existential and struct X
if you re-read my original message.

Thanks,
Jon

On Jan 23, 2017, at 5:10 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

This would get very confusing, as it would be impossible for a class to
distinguish conforming to protocol X vs. inheriting from base class X, or
else we would have to change the spelling for that as well. Moreover, you
would have no way of distinguishing the existential X from the struct X. I
see nothing wrong with the clarity afforded by naming the distinct things
`FooProtocol` and `Foo`, and I disagree that there's anything "simplifying"
about naming two different things with one name.

On Mon, Jan 23, 2017 at 6:13 PM, Jonathan Hull via swift-evolution < > swift-evolution@swift.org> wrote:

Have we considered allowing a struct/class/enum to have the same name as a
protocol as long as it conforms to the protocol? Type declarations would
have to always mean the protocol (which includes the concrete type as
well). Static functions would always apply to the concrete type.

Seems like a good way to support having a default implementation of a
protocol. I am always running into the awkward naming issues around this...

        protocol X {
                //yada yada
        }

        struct X { //Implicitly adheres to protocol X (because it must)
                init(){…}
        }

        let myVar:X //This refers to the protocol
        let otherVar = X() //This makes the struct

If we do need to be able to spell the concrete type for other uses, we
could probably do something like: ‘concrete(X)’ which isn’t pretty, but is
there for the rare times it is needed for utility. I can’t think of any
reason except making an array of the concrete type.

I am guessing there is a subtle technical reason this won’t work, but I
wanted to mention it now just in case it is possible. Seems like it could
have a large (simplifying) effect on the namespace of the standard library.

Thanks,
Jon
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution