swift-users Digest, Vol 3, Issue 15

You are correct that if you are using the protocol type to interact with the instance then the method defined in the protocol extension will be called however if it is type casted to a concrete type which has a method that overrides the method in the protocol extension then the method in the concrete type would be called. This following code illustrates this:

protocol TestProtocol {
    var num1: Int {get set}
    var num2: Int {get set}
}

extension TestProtocol {
    func doMath() -> Int {
        return num1 + num2
    }
}

struct MyTypeOne: TestProtocol {
    var num1 = 1
    var num2 = 2
}

struct MyTypeTwo: TestProtocol {
    var num1 = 1
    var num2 = 2
    func doMath() -> Int {
        return num2 - num1
    }
}

var one = MyTypeOne()
var two = MyTypeTwo()

print("MyTypeOne: \(one.doMath())")
print("MyTypeTwo: \(two.doMath())")

var t: TestProtocol = two
print("TestProtocol \(t.doMath())")

The output from this code would be:

MyTypeOne: 3
MyTypeTwo: 1
TestProtocol 3

This shows that when calling the doMath() on the MyTypeTwo instance calls the method defined in the MyTypeTwo structure however if we call the method on the same instance but it being typecast as the protocol will call the method in the protocol.

For the most part we would access the types though the interface provided by the protocol however using the “is” keyword we can check if a type is an instance of a particular concrete type or use the typecast operator to downcast the instance. This would give us access to the method that is defined in the concrete type. This can certainly be useful in certain situations. I do agree that these situation should be avoided however it is something that can be done which we can not do with global functions. I was just trying to list some of the differences between protocol extensions and global functions. Honestly, and this is my personal opinion, I believe there is significant difference between protocol extensions and global functions: avoiding the global scope, using constraints, better code organization to name a couple, overriding, self parameter, better code manageability just to name some of them.

Protocol Extensions are there so we can add functionality to a group of types that conform to a specific protocol that meets any constraints defined by the extension. This allows us to avoid duplicate code similar to what we did with super classes in the OOP world. However with protocols we can create very specific protocols rather than large monolithic superclasses. Without protocol extensions we would have to revert to creating global functions however, in my opinion once again, the protocol extensions is a better option. That is what I was trying to get across.

Jon

···

On Feb 16, 2016, at 8:30 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

We can override functionality provided from a protocol extension if we need specific functionality for a particular type.

No you can't. Protocol extension methods (that is, methods declared only in an extension, as opposed to default implementations, which are both declared in the protocol and defined in an extension) are statically dispatched, so calling them on the protocol witness will always use the extension's implementation, even if some concrete type conforming to the protocol has a different implementation with the same name and signature.

(I've worked on a proposal in the past that would require keywords to make this behavior clearer, but I've had trouble getting it through.)

In any case, I'm pretty sure that's what Daniel means when he says extension methods are exactly equivalent to global functions. Sure, they appear after a dot, have an implicit self parameter, and are scoped to a particular type, but there's nothing dynamic about their behavior—they're not overridable in any useful sense.

--
Brent Royal-Gordon
Architechies

The difference is that they can function as overrides of requirements,
which global functions cannot (insert obligatory caveat about operator
hack here).

···

on Tue Feb 16 2016, Brent Royal-Gordon <swift-users-AT-swift.org> wrote:

We can override functionality provided from a protocol extension if

we need specific functionality for a particular type.

No you can't. Protocol extension methods (that is, methods declared
only in an extension, as opposed to default implementations, which are
both declared in the protocol and defined in an extension) are
statically dispatched, so calling them on the protocol witness will
always use the extension's implementation, even if some concrete type
conforming to the protocol has a different implementation with the
same name and signature.

(I've worked on a proposal in the past that would require keywords to
make this behavior clearer, but I've had trouble getting it through.)

In any case, I'm pretty sure that's what Daniel means when he says
extension methods are exactly equivalent to global functions. Sure,
they appear after a dot, have an implicit self parameter, and are
scoped to a particular type, but there's nothing dynamic about their
behavior—they're not overridable in any useful sense.

--
-Dave

I am going to try to answer all of your questions at once (sorry if I
miss anything), which is why I am top posting here.

Forty lashes with a wet noodle for you, my friend.

Also sorry for the long e-mails

Okay, fifty :-)

but I am trying to capture what I want to say and still keep the
response as small as possible but I am not doing a good job at the
small part.

Maybe you ran out of time.
http://quoteinvestigator.com/2012/04/28/shorter-letter/

As an architect and developer, I look at POP as more than just
developing to an interface. If we were to take the view that POP was
simply about an interface first design then we would be able to say
that Java and C# could be POP languages. While there are plenty of
approaches like OSGI that take an interface first approach, they still
use the fundamentals of OOP in their design (reference types, class
hierarchies).

You say that you do not view extensions themselves as a fundamental
part of POP. My response to that is: Can we really have POP without
protocol extensions? Without protocol extensions, if we had common
functionality between our conforming types we would need to take one
of the following three approaches:

    * We would need to create large monolithic super classes as we do
with OOP that all conforming types would also inherit from.

    * Have large amounts of duplicate code in our types

    * Use global functions

My point about protocol extensions has to do with the “extension” part
rather than the “protocol” part. The fundamental property of extensions
is that you can add to a type's interface *without owning that type*.
There are other ways one could express the same kind of code sharing for
protocols without having a mechanism that allows arbitrary extension by
authors that don't own the protocol. For example, the same basic
expressive capabilities were built into
http://www.generic-programming.org/software/ConceptGCC/, which in many
ways was a precursor to Swift's generics system in the form of concept
maps. Extensions happened to be the most convenient vehicle for
bringing these capabilities into Swift.

While these approaches have worked in the past, in my opinion (and I
know some will argue this) they are not ideal solutions. With
protocol extensions we are able to have our cake and eat it too (and
who does not like cake). We are able to define smaller, very specific
protocols (rather than monolithic super classes) and also provide an
implementation for functionality that is common to our conforming
types thereby avoiding duplicate code and global functions. Therefore
would POP really be a viable programming paradigm without protocol
extensions?

Yes, but you'd need other mechanisms to achieve the same ends.

If you take that logic further, then what is actually part of the POP
paradigm? Apple really hasn’t defined that and has seemed to have
left that question up to the community.

Mea culpa. But we only have so much time for writing blog posts,
etc. while simultaneously changing the face of all Apple APIs and trying
to develop the Swift standard library ;-)

I'm just glad there are thoughtful and insightful authors like you out
there to pick up the thread.

Looking at that question from an architect’s point of view then I can
see a number of area that we can include. In my book I included
sections on the type choices that we have (classes, structures,
enumerations, tuples…), error handling, protocols and extensions.
From one of your earlier e-mails, hindsight being 20-20, maybe I
should have had a separate section on generics. I did touch on
generics in the protocol chapter but maybe I do need to expand on
that.

Great idea.

Where I see ECS design to be similar to POP (in my opinion) is in ECS
every entity consists of one or more components which add additional
behavior or functionality to the entity. With POP we can think of the
components as the protocol (with protocol extensions). Then each
protocol that a type conforms to will add additional behavior or
functionality similar to ECS. With OOP and single inheritance as we
have with Swift, we have the monolithic super classes rather than
smaller components like POP and ECS. This is one of the things that
has drawn me to POP.

If what you're saying is that POP is better than OOP for decomposing
designs in Swift, I won't argue. ECS is a different path to a granular
design, but AFAICT that's where any similarity to POP ends.

···

on Sun Mar 06 2016, Jon Hoffman <hoffman.jon-AT-gmail.com> wrote:

I kept the e-mail as small as I could and hopefully I still got my ideas across.

Jon

On Mar 6, 2016, at 1:30 AM, Dave Abrahams via swift-users <swift-users@swift.org> wrote:

on Sat Mar 05 2016, Jon Hoffman <swift-users-AT-swift.org> wrote:

On Feb 25, 2016, at 7:38 PM, Dave Abrahams via swift-users <swift-users@swift.org> wrote:

on Mon Feb 15 2016, Jon Hoffman <swift-users-AT-swift.org> wrote:

Thank you for the feedback however you cannot design the code as you
describe, if I understand your explanation correctly, because one of the
requirements is the animals may be apart of multiple categories. As the
example in the post shows the alligator belongs to both the Land and the
Sea categories. In you description that would mean that the Alligator type
would need to be a subclass of both the Land and Sea superclasses which is
not permitted. Remember that one of the drawbacks with OOP is a subclass
can only inherit from one superclass.

That's true in Swift, but not in all realizations of OOP. If your
article is merely using protocols to get the benefits of multiple
inheritance from abstract classes, it may not touch at all on what
differentiates OOP from POP at a fundamental level.

You are absolutely correct; with protocols we do gain a lot more than
just multiple inheritance. In this post I touch on protocol
composition

In what ways do you see “protocol composition” as being distinct from
“multiple inheritance?”

and also extensions just to name two of them.

I don't view extensions themselves as a fundamental part of POP. After
all, we can extend classes as well as protocols. It's possible to
express the things that we do with protocol extensions using other
language features that don't make types fully open for extension outside
the scope in which they're defined.

One of the things that I do emphasize when I talk about
Protocol-Oriented programming is it is about so much more than just
the protocol.

Do tell! What do you mean?

To be honest, I think that Apple may have done a disservice to POP by
giving it the name “Protocol-Oriented Programming”. With OOP and POP
having such similar names, people tend to relate them together and in
my opinion, how you design your application with POP is fundamentally
different than with OOP.

Isn't that the whole point? It's a different orientation.

The way in which OOP is “object oriented” is that it starts with the
premise that the fundamental unit of abstraction is the object,
i.e. class instance. The way in which POP is “protocol oriented” is
that it says the fundamental unit of abstraction is the protocol.

Hopefully I will be able to write some additional posts about
designing applications in a POP way using case studies. Just a matter
of finding time.

In one of the e-mails about this post, someone mentioned
Entity-Component Systems
(https://en.wikipedia.org/wiki/Entity_component_system\). I personally
have not used ECS however from what I read from the links provided in
that e-mail, in a lot of ways the design philosophy behind POP seems
to be closer to ECS than OOP

From what I read there, an ECS has almost nothing in common with what
I've tried to capture as protocol-oriented programming. In particular,
ECS seems to much closer to “stringly typed” or dictionary-oriented
programming, with lots of dynamic interrogation for object properties
rather than use of strong static typing.

--
-Dave

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

--
-Dave

Same, and part of the decision rationale reiterated the point that Swift is foremost a pragmatic language for getting things done :).

Austin

···

On Mar 9, 2016, at 12:17 PM, Shawn Erickson via swift-users <swift-users@swift.org> wrote:

On Wed, Mar 9, 2016 at 12:15 PM Evan Maloney via swift-users <swift-users@swift.org> wrote:
Personally, what I love about Swift is that it doesn't fit into just one "oriented programming" box. But perhaps I'm in the minority.

You can count me in that minority :)
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

The method in the concrete type does not override the method from the
protocol extension, it merely shadows that method.

Dmitri

···

On Tue, Feb 16, 2016 at 6:28 PM, Jon Hoffman via swift-users <swift-users@swift.org> wrote:

You are correct that if you are using the protocol type to interact with the
instance then the method defined in the protocol extension will be called
however if it is type casted to a concrete type which has a method that
overrides the method in the protocol extension then the method in the
concrete type would be called.

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/

Yes, the method from the concrete type shadows the method from the protocol extension is better terminology. Thanks for pointing that out.

···

On Feb 16, 2016, at 9:49 PM, Dmitri Gribenko <gribozavr@gmail.com> wrote:

On Tue, Feb 16, 2016 at 6:28 PM, Jon Hoffman via swift-users > <swift-users@swift.org> wrote:

You are correct that if you are using the protocol type to interact with the
instance then the method defined in the protocol extension will be called
however if it is type casted to a concrete type which has a method that
overrides the method in the protocol extension then the method in the
concrete type would be called.

The method in the concrete type does not override the method from the
protocol extension, it merely shadows that method.

Dmitri

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/

And your example is exactly equivalent to the below:

protocol TestProtocol {
  var num1: Int {get set}
  var num2: Int {get set}
}

func doMath(t: TestProtocol) -> Int {
  return t.num1 + t.num2
}

struct MyTypeOne: TestProtocol {
  var num1 = 1
  var num2 = 2
}

struct MyTypeTwo: TestProtocol {
  var num1 = 1
  var num2 = 2
  func doMath() -> Int {
    return num2 - num1
  }
}

var one = MyTypeOne()
var two = MyTypeTwo()

print("MyTypeOne: \(doMath(one))")
print("MyTypeTwo: \(two.doMath())")

var t: TestProtocol = two
print("TestProtocol \(doMath(t))")

What the protocol extension gives you, all that it gives you, is a different syntax for doing the exact same thing. Where your code shines IMHO is when you want to then use the return value as a parameter to yet another function.

two.doMath().handleResult() is far cleaner, and better expresses what is happening, than handleResult(doMath(one))

All IMHO of course.

···

On Feb 16, 2016, at 9:28 PM, Jon Hoffman <hoffman.jon@gmail.com> wrote:

You are correct that if you are using the protocol type to interact with the instance then the method defined in the protocol extension will be called however if it is type casted to a concrete type which has a method that overrides the method in the protocol extension then the method in the concrete type would be called. This following code illustrates this:

protocol TestProtocol {
    var num1: Int {get set}
    var num2: Int {get set}
}

extension TestProtocol {
    func doMath() -> Int {
        return num1 + num2
    }
}

struct MyTypeOne: TestProtocol {
    var num1 = 1
    var num2 = 2
}

struct MyTypeTwo: TestProtocol {
    var num1 = 1
    var num2 = 2
    func doMath() -> Int {
        return num2 - num1
    }
}

var one = MyTypeOne()
var two = MyTypeTwo()

print("MyTypeOne: \(one.doMath())")
print("MyTypeTwo: \(two.doMath())")

var t: TestProtocol = two
print("TestProtocol \(t.doMath())")

The output from this code would be:

MyTypeOne: 3
MyTypeTwo: 1
TestProtocol 3

This shows that when calling the doMath() on the MyTypeTwo instance calls the method defined in the MyTypeTwo structure however if we call the method on the same instance but it being typecast as the protocol will call the method in the protocol.

For the most part we would access the types though the interface provided by the protocol however using the “is” keyword we can check if a type is an instance of a particular concrete type or use the typecast operator to downcast the instance. This would give us access to the method that is defined in the concrete type. This can certainly be useful in certain situations. I do agree that these situation should be avoided however it is something that can be done which we can not do with global functions. I was just trying to list some of the differences between protocol extensions and global functions. Honestly, and this is my personal opinion, I believe there is significant difference between protocol extensions and global functions: avoiding the global scope, using constraints, better code organization to name a couple, overriding, self parameter, better code manageability just to name some of them.

Protocol Extensions are there so we can add functionality to a group of types that conform to a specific protocol that meets any constraints defined by the extension. This allows us to avoid duplicate code similar to what we did with super classes in the OOP world. However with protocols we can create very specific protocols rather than large monolithic superclasses. Without protocol extensions we would have to revert to creating global functions however, in my opinion once again, the protocol extensions is a better option. That is what I was trying to get across.

Jon

On Feb 16, 2016, at 8:30 PM, Brent Royal-Gordon <brent@architechies.com <mailto:brent@architechies.com>> wrote:

We can override functionality provided from a protocol extension if we need specific functionality for a particular type.

No you can't. Protocol extension methods (that is, methods declared only in an extension, as opposed to default implementations, which are both declared in the protocol and defined in an extension) are statically dispatched, so calling them on the protocol witness will always use the extension's implementation, even if some concrete type conforming to the protocol has a different implementation with the same name and signature.

(I've worked on a proposal in the past that would require keywords to make this behavior clearer, but I've had trouble getting it through.)

In any case, I'm pretty sure that's what Daniel means when he says extension methods are exactly equivalent to global functions. Sure, they appear after a dot, have an implicit self parameter, and are scoped to a particular type, but there's nothing dynamic about their behavior—they're not overridable in any useful sense.

--
Brent Royal-Gordon
Architechies

Technically true, but not really interesting because no instances of a
protocol extension exist. Instances of the protocol (and generic
parameters constrained thereto) do exist, and the method in the concrete
type “overrides the lack of implementation” in the protocol itself,
which otherwise would have been satisfied by the extension.
Semantically, that is indistinguishable from the extension's
implementation being a default in the protocol itself, which is
overridden.

···

on Tue Feb 16 2016, Dmitri Gribenko <swift-users-AT-swift.org> wrote:

On Tue, Feb 16, 2016 at 6:28 PM, Jon Hoffman via swift-users > <swift-users@swift.org> wrote:

You are correct that if you are using the protocol type to interact with the
instance then the method defined in the protocol extension will be called
however if it is type casted to a concrete type which has a method that
overrides the method in the protocol extension then the method in the
concrete type would be called.

The method in the concrete type does not override the method from the
protocol extension, it merely shadows that method.

--
-Dave

I am going to try to answer all of your questions at once (sorry if I
miss anything), which is why I am top posting here.

Forty lashes with a wet noodle for you, my friend.

Not the wet noodle, anything but that. :)

Also sorry for the long e-mails

Okay, fifty :-)

but I am trying to capture what I want to say and still keep the
response as small as possible but I am not doing a good job at the
small part.

Maybe you ran out of time.
http://quoteinvestigator.com/2012/04/28/shorter-letter/

Oh if we only had more time to do all of the things we wanted or at least to shorten our e-mails.

As an architect and developer, I look at POP as more than just
developing to an interface. If we were to take the view that POP was
simply about an interface first design then we would be able to say
that Java and C# could be POP languages. While there are plenty of
approaches like OSGI that take an interface first approach, they still
use the fundamentals of OOP in their design (reference types, class
hierarchies).

You say that you do not view extensions themselves as a fundamental
part of POP. My response to that is: Can we really have POP without
protocol extensions? Without protocol extensions, if we had common
functionality between our conforming types we would need to take one
of the following three approaches:

   * We would need to create large monolithic super classes as we do
with OOP that all conforming types would also inherit from.

   * Have large amounts of duplicate code in our types

   * Use global functions

My point about protocol extensions has to do with the “extension” part
rather than the “protocol” part. The fundamental property of extensions
is that you can add to a type's interface *without owning that type*.
There are other ways one could express the same kind of code sharing for
protocols without having a mechanism that allows arbitrary extension by
authors that don't own the protocol. For example, the same basic
expressive capabilities were built into
http://www.generic-programming.org/software/ConceptGCC/, which in many
ways was a precursor to Swift's generics system in the form of concept
maps. Extensions happened to be the most convenient vehicle for
bringing these capabilities into Swift.

I agree that there is other ways we can do code sharing besides
protocol extensions however as you pointed out extensions are the most
convenient way. I would also say that in my opinion protocol
extensions are also the most elegant and one of the easiest for new
programmers to learn when coming from an OOP background. Developers
coming from a functional backgrounds can still use global methods.

Well, global functions (except operators—an evil hack that I expect to
be removed someday [¹]) don't actually allow us to provide default
implementations for protocol requirements, so they're not a substitute
for protocol extensions.

To help grow POP with Swift, in my opinion, there really should be a
standard or recommended way for adding common functionality even if
some developers prefer to take a different approach.

I'm not talking about alternative approaches that are available in
Swift. I'm talking about different ways to get the basic generics
capabilities that fall out of protocol extensions, but using language
features we don't have. I agree that protocol extensions are a
beautifully elegant way to get these capabilities, but you could still
do the same kind of programming with a different mechanism that doesn't
allow for open-ended extension.

This will allow us to write books and articles about POP and show a
consistent approach. If different authors take different approaches,
it could get confusing for other developers that are trying to figure
out what POP is. To me standardizing on protocol extensions make the
most sense.

Of course; that's the way it's done in Swift. I'm trying to say that in
principle you can take a protocol-oriented approach in many different
languages and express the same kinds of ideas as we do in Swift, though
it may not be as elegant. Heck, I was doing much of this in C++ for
years, and C++ doesn't even have protocols! Of course, it's much uglier
to do so. Swift is the best language I've seen for expressing the
protocol-oriented approach. It's also protocol-oriented at its core,
using protocols for literals, looping, and bridging to Objective C.

I can see the benefits with also showing other approaches at the same
time we show protocol extensions larger print mediums like books
however having that standard approach will make it easier all the way
around.

No, I don't suggest you show other approaches. I'm just trying to
suggest that you think of what POP means separately from the language
mechanisms used to realize it.

While these approaches have worked in the past, in my opinion (and I
know some will argue this) they are not ideal solutions. With
protocol extensions we are able to have our cake and eat it too (and
who does not like cake). We are able to define smaller, very specific
protocols (rather than monolithic super classes) and also provide an
implementation for functionality that is common to our conforming
types thereby avoiding duplicate code and global functions. Therefore
would POP really be a viable programming paradigm without protocol
extensions?

Yes, but you'd need other mechanisms to achieve the same ends.

If you take that logic further, then what is actually part of the POP
paradigm? Apple really hasn’t defined that and has seemed to have
left that question up to the community.

Mea culpa. But we only have so much time for writing blog posts,
etc. while simultaneously changing the face of all Apple APIs and trying
to develop the Swift standard library ;-)

With all of the talent at Apple, you should have all that completed
next week and still have time for a paint ball tournament, right? :)

Mmm, delicious paint balls. Yum.

I'm just glad there are thoughtful and insightful authors like you out
there to pick up the thread.

Thank you for the compliment

Looking at that question from an architect’s point of view then I can
see a number of area that we can include. In my book I included
sections on the type choices that we have (classes, structures,
enumerations, tuples…), error handling, protocols and extensions.
From one of your earlier e-mails, hindsight being 20-20, maybe I
should have had a separate section on generics. I did touch on
generics in the protocol chapter but maybe I do need to expand on
that.

Great idea.

Generics are a pretty broad subject to cover all at once, what parts
do you think matter the most when it comes to POP?

All of them, sorry ;-)

What makes protocols in Swift different from Java interfaces (or
Objective-C protocols for that matter) is that they support static
polymorphism and generic programming.

Where I see ECS design to be similar to POP (in my opinion) is in ECS
every entity consists of one or more components which add additional
behavior or functionality to the entity. With POP we can think of the
components as the protocol (with protocol extensions). Then each
protocol that a type conforms to will add additional behavior or
functionality similar to ECS. With OOP and single inheritance as we
have with Swift, we have the monolithic super classes rather than
smaller components like POP and ECS. This is one of the things that
has drawn me to POP.

If what you're saying is that POP is better than OOP for decomposing
designs in Swift, I won't argue. ECS is a different path to a granular
design, but AFAICT that's where any similarity to POP ends.

I do not know enough about ECS to comment any further than the
granular approach but yes I think that approach is similar to what POP
is.

I kept the e-mail as small as I could and hopefully I still got my ideas across.

Jon

Thank you for the feedback however you cannot design the code as you
describe, if I understand your explanation correctly, because one of the
requirements is the animals may be apart of multiple categories. As the
example in the post shows the alligator belongs to both the Land and the
Sea categories. In you description that would mean that the Alligator type
would need to be a subclass of both the Land and Sea superclasses which is
not permitted. Remember that one of the drawbacks with OOP is a subclass
can only inherit from one superclass.

That's true in Swift, but not in all realizations of OOP. If your
article is merely using protocols to get the benefits of multiple
inheritance from abstract classes, it may not touch at all on what
differentiates OOP from POP at a fundamental level.

You are absolutely correct; with protocols we do gain a lot more than
just multiple inheritance. In this post I touch on protocol
composition

In what ways do you see “protocol composition” as being distinct from
“multiple inheritance?”

and also extensions just to name two of them.

I don't view extensions themselves as a fundamental part of POP. After
all, we can extend classes as well as protocols. It's possible to
express the things that we do with protocol extensions using other
language features that don't make types fully open for extension outside
the scope in which they're defined.

One of the things that I do emphasize when I talk about
Protocol-Oriented programming is it is about so much more than just
the protocol.

Do tell! What do you mean?

To be honest, I think that Apple may have done a disservice to POP by
giving it the name “Protocol-Oriented Programming”. With OOP and POP
having such similar names, people tend to relate them together and in
my opinion, how you design your application with POP is fundamentally
different than with OOP.

Isn't that the whole point? It's a different orientation.

The way in which OOP is “object oriented” is that it starts with the
premise that the fundamental unit of abstraction is the object,
i.e. class instance. The way in which POP is “protocol oriented” is
that it says the fundamental unit of abstraction is the protocol.

Hopefully I will be able to write some additional posts about
designing applications in a POP way using case studies. Just a matter
of finding time.

In one of the e-mails about this post, someone mentioned
Entity-Component Systems
(https://en.wikipedia.org/wiki/Entity_component_system\). I personally
have not used ECS however from what I read from the links provided in
that e-mail, in a lot of ways the design philosophy behind POP seems
to be closer to ECS than OOP

From what I read there, an ECS has almost nothing in common with what
I've tried to capture as protocol-oriented programming. In particular,
ECS seems to much closer to “stringly typed” or dictionary-oriented
programming, with lots of dynamic interrogation for object properties
rather than use of strong static typing.

--
-Dave

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

--
-Dave

Footnotes:
[¹] https://github.com/apple/swift/blob/master/test/Prototypes/GenericDispatch.swift

···

on Mon Mar 07 2016, Jon Hoffman <hoffman.jon-AT-gmail.com> wrote:

On Mar 7, 2016, at 12:16 AM, Dave Abrahams <dabrahams@apple.com> wrote:
on Sun Mar 06 2016, Jon Hoffman <hoffman.jon-AT-gmail.com> wrote:

On Mar 6, 2016, at 1:30 AM, Dave Abrahams via swift-users <swift-users@swift.org> wrote:
on Sat Mar 05 2016, Jon Hoffman <swift-users-AT-swift.org> wrote:

On Feb 25, 2016, at 7:38 PM, Dave Abrahams via swift-users <swift-users@swift.org> wrote:
on Mon Feb 15 2016, Jon Hoffman <swift-users-AT-swift.org> wrote:

--
-Dave

I am going to try to answer all of your questions at once (sorry if I
miss anything), which is why I am top posting here.

Forty lashes with a wet noodle for you, my friend.

Not the wet noodle, anything but that. :)

Also sorry for the long e-mails

Okay, fifty :-)

but I am trying to capture what I want to say and still keep the
response as small as possible but I am not doing a good job at the
small part.

Maybe you ran out of time.
If I Had More Time, I Would Have Written a Shorter Letter – Quote Investigator®

Oh if we only had more time to do all of the things we wanted or at least to shorten our e-mails.

As an architect and developer, I look at POP as more than just
developing to an interface. If we were to take the view that POP was
simply about an interface first design then we would be able to say
that Java and C# could be POP languages. While there are plenty of
approaches like OSGI that take an interface first approach, they still
use the fundamentals of OOP in their design (reference types, class
hierarchies).

You say that you do not view extensions themselves as a fundamental
part of POP. My response to that is: Can we really have POP without
protocol extensions? Without protocol extensions, if we had common
functionality between our conforming types we would need to take one
of the following three approaches:

   * We would need to create large monolithic super classes as we do
with OOP that all conforming types would also inherit from.

   * Have large amounts of duplicate code in our types

   * Use global functions

My point about protocol extensions has to do with the “extension” part
rather than the “protocol” part. The fundamental property of extensions
is that you can add to a type's interface *without owning that type*.
There are other ways one could express the same kind of code sharing for
protocols without having a mechanism that allows arbitrary extension by
authors that don't own the protocol. For example, the same basic
expressive capabilities were built into
http://www.generic-programming.org/software/ConceptGCC/, which in many
ways was a precursor to Swift's generics system in the form of concept
maps. Extensions happened to be the most convenient vehicle for
bringing these capabilities into Swift.

I agree that there is other ways we can do code sharing besides protocol extensions however as you pointed out extensions are the most convenient way. I would also say that in my opinion protocol extensions are also the most elegant and one of the easiest for new programmers to learn when coming from an OOP background. Developers coming from a functional backgrounds can still use global methods.

To help grow POP with Swift, in my opinion, there really should be a standard or recommended way for adding common functionality even if some developers prefer to take a different approach. This will allow us to write books and articles about POP and show a consistent approach. If different authors take different approaches, it could get confusing for other developers that are trying to figure out what POP is. To me standardizing on protocol extensions make the most sense.

I can see the benefits with also showing other approaches at the same time we show protocol extensions larger print mediums like books however having that standard approach will make it easier all the way around.

While these approaches have worked in the past, in my opinion (and I
know some will argue this) they are not ideal solutions. With
protocol extensions we are able to have our cake and eat it too (and
who does not like cake). We are able to define smaller, very specific
protocols (rather than monolithic super classes) and also provide an
implementation for functionality that is common to our conforming
types thereby avoiding duplicate code and global functions. Therefore
would POP really be a viable programming paradigm without protocol
extensions?

Yes, but you'd need other mechanisms to achieve the same ends.

If you take that logic further, then what is actually part of the POP
paradigm? Apple really hasn’t defined that and has seemed to have
left that question up to the community.

Mea culpa. But we only have so much time for writing blog posts,
etc. while simultaneously changing the face of all Apple APIs and trying
to develop the Swift standard library ;-)

With all of the talent at Apple, you should have all that completed next week and still have time for a paint ball tournament, right? :)

I'm just glad there are thoughtful and insightful authors like you out
there to pick up the thread.

Thank you for the compliment

Looking at that question from an architect’s point of view then I can
see a number of area that we can include. In my book I included
sections on the type choices that we have (classes, structures,
enumerations, tuples…), error handling, protocols and extensions.
From one of your earlier e-mails, hindsight being 20-20, maybe I
should have had a separate section on generics. I did touch on
generics in the protocol chapter but maybe I do need to expand on
that.

Great idea.

Generics are a pretty broad subject to cover all at once, what parts do you think matter the most when it comes to POP?

Where I see ECS design to be similar to POP (in my opinion) is in ECS
every entity consists of one or more components which add additional
behavior or functionality to the entity. With POP we can think of the
components as the protocol (with protocol extensions). Then each
protocol that a type conforms to will add additional behavior or
functionality similar to ECS. With OOP and single inheritance as we
have with Swift, we have the monolithic super classes rather than
smaller components like POP and ECS. This is one of the things that
has drawn me to POP.

If what you're saying is that POP is better than OOP for decomposing
designs in Swift, I won't argue. ECS is a different path to a granular
design, but AFAICT that's where any similarity to POP ends.

I do not know enough about ECS to comment any further than the granular approach but yes I think that approach is similar to what POP is.

···

On Mar 7, 2016, at 12:16 AM, Dave Abrahams <dabrahams@apple.com> wrote:
on Sun Mar 06 2016, Jon Hoffman <hoffman.jon-AT-gmail.com> wrote:

I kept the e-mail as small as I could and hopefully I still got my ideas across.

Jon

Forty lashes with a wet noodle for you, my friend.

that's so cruel… I think it's unfair of you to join this discussion: It's like Hemingway dropping in an oral exam about "The Old Man and the Sea", starting to ask questions ;-)

I guess it is the terminology of “exactly equivalent” is where you are losing me because I do agree that our two code samples are functionally equivalent but I would be hard pressed to say they are exactly equivalent.

Before I go on, I hope it is all right to have this discussion on this group because I do enjoy friendly discussions like this. I believe it helps everyone to see multiple points of view and to see advantages to both sides in a friendly manner.

Lets say that a year from now we receive requirements that some of our types will have three numbers while others will stay at two numbers. We also have the requirement that the math function will be preformed on all three numbers for the types that contain three numbers. With protocol extensions, using protocol composition and constraints we could rewrite our code like this:

protocol TestProtocol1 {
    var num1: Int {get set}
    var num2: Int {get set}
}

protocol TestProtocol2 {
    var num3: Int {get set}
}

extension TestProtocol1 where Self: TestProtocol2 {
    func doMath() -> Int {
        return num1 + num2 + num3
    }
}

extension TestProtocol1 {
    func doMath() -> Int {
        return num1 + num2
    }
}

struct MyTypeOne: TestProtocol1, TestProtocol2 {
    var num1 = 1
    var num2 = 2
    var num3 = 3
}

struct MyTypeTwo: TestProtocol1 {
    var num1 = 1
    var num2 = 2
}

var one = MyTypeOne()
var two = MyTypeTwo()

print("MyTypeOne: \(one.doMath())")
print("MyTypeTwo: \(two.doMath())")

This example would print out:

MyTypeOne: 6
MyTypeTwo: 3
We could create a global function and use the “is” operator within the function to test if the type conforms to the TestProtocol2 protocol or not however I believe that the protocol extensions approach using protocol composition and constraints like this is much cleaner and easier to manage than the global function approach.

So I would definitely agree that functionally they can be equivalent but, in my opinion, I just have trouble agreeing that they are exactly equivalent.

Jon

···

On Feb 16, 2016, at 10:36 PM, Daniel Tartaglia <danielt1263@gmail.com> wrote:

And your example is exactly equivalent to the below:

protocol TestProtocol {
  var num1: Int {get set}
  var num2: Int {get set}
}

func doMath(t: TestProtocol) -> Int {
  return t.num1 + t.num2
}

struct MyTypeOne: TestProtocol {
  var num1 = 1
  var num2 = 2
}

struct MyTypeTwo: TestProtocol {
  var num1 = 1
  var num2 = 2
  func doMath() -> Int {
    return num2 - num1
  }
}

var one = MyTypeOne()
var two = MyTypeTwo()

print("MyTypeOne: \(doMath(one))")
print("MyTypeTwo: \(two.doMath())")

var t: TestProtocol = two
print("TestProtocol \(doMath(t))")

What the protocol extension gives you, all that it gives you, is a different syntax for doing the exact same thing. Where your code shines IMHO is when you want to then use the return value as a parameter to yet another function.

two.doMath().handleResult() is far cleaner, and better expresses what is happening, than handleResult(doMath(one))

All IMHO of course.

On Feb 16, 2016, at 9:28 PM, Jon Hoffman <hoffman.jon@gmail.com <mailto:hoffman.jon@gmail.com>> wrote:

You are correct that if you are using the protocol type to interact with the instance then the method defined in the protocol extension will be called however if it is type casted to a concrete type which has a method that overrides the method in the protocol extension then the method in the concrete type would be called. This following code illustrates this:

protocol TestProtocol {
    var num1: Int {get set}
    var num2: Int {get set}
}

extension TestProtocol {
    func doMath() -> Int {
        return num1 + num2
    }
}

struct MyTypeOne: TestProtocol {
    var num1 = 1
    var num2 = 2
}

struct MyTypeTwo: TestProtocol {
    var num1 = 1
    var num2 = 2
    func doMath() -> Int {
        return num2 - num1
    }
}

var one = MyTypeOne()
var two = MyTypeTwo()

print("MyTypeOne: \(one.doMath())")
print("MyTypeTwo: \(two.doMath())")

var t: TestProtocol = two
print("TestProtocol \(t.doMath())")

The output from this code would be:

MyTypeOne: 3
MyTypeTwo: 1
TestProtocol 3

This shows that when calling the doMath() on the MyTypeTwo instance calls the method defined in the MyTypeTwo structure however if we call the method on the same instance but it being typecast as the protocol will call the method in the protocol.

For the most part we would access the types though the interface provided by the protocol however using the “is” keyword we can check if a type is an instance of a particular concrete type or use the typecast operator to downcast the instance. This would give us access to the method that is defined in the concrete type. This can certainly be useful in certain situations. I do agree that these situation should be avoided however it is something that can be done which we can not do with global functions. I was just trying to list some of the differences between protocol extensions and global functions. Honestly, and this is my personal opinion, I believe there is significant difference between protocol extensions and global functions: avoiding the global scope, using constraints, better code organization to name a couple, overriding, self parameter, better code manageability just to name some of them.

Protocol Extensions are there so we can add functionality to a group of types that conform to a specific protocol that meets any constraints defined by the extension. This allows us to avoid duplicate code similar to what we did with super classes in the OOP world. However with protocols we can create very specific protocols rather than large monolithic superclasses. Without protocol extensions we would have to revert to creating global functions however, in my opinion once again, the protocol extensions is a better option. That is what I was trying to get across.

Jon

On Feb 16, 2016, at 8:30 PM, Brent Royal-Gordon <brent@architechies.com <mailto:brent@architechies.com>> wrote:

We can override functionality provided from a protocol extension if we need specific functionality for a particular type.

No you can't. Protocol extension methods (that is, methods declared only in an extension, as opposed to default implementations, which are both declared in the protocol and defined in an extension) are statically dispatched, so calling them on the protocol witness will always use the extension's implementation, even if some concrete type conforming to the protocol has a different implementation with the same name and signature.

(I've worked on a proposal in the past that would require keywords to make this behavior clearer, but I've had trouble getting it through.)

In any case, I'm pretty sure that's what Daniel means when he says extension methods are exactly equivalent to global functions. Sure, they appear after a dot, have an implicit self parameter, and are scoped to a particular type, but there's nothing dynamic about their behavior—they're not overridable in any useful sense.

--
Brent Royal-Gordon
Architechies

If you go further, you will realize that Objects are only Structures with
some function pointers.

The differences on structured programming and object-oriented programming
can be reduced to a "syntax level" too.

POP for example encourages more use of multiple (inheritance|composition)
than OO. The pattern is more important than syntax.

However I agree, Swift POP still have many limitations and almost no
innovation. There are several proposed improvements to protocols that
should arrive in the next versions, maybe then people start to consider POP
a true paradigm. For now is just a syntax sugar for *Composition over
inheritance*.

···

Em qua, 17 de fev de 2016 às 01:35, Daniel Tartaglia via swift-users < swift-users@swift.org> escreveu:

And your example is exactly equivalent to the below:

protocol TestProtocol {
var num1: Int {get set}
var num2: Int {get set}
}

func doMath(t: TestProtocol) -> Int {
return t.num1 + t.num2
}

struct MyTypeOne: TestProtocol {
var num1 = 1
var num2 = 2
}

struct MyTypeTwo: TestProtocol {
var num1 = 1
var num2 = 2
func doMath() -> Int {
return num2 - num1
}
}

var one = MyTypeOne()
var two = MyTypeTwo()

print("MyTypeOne: \(doMath(one))")
print("MyTypeTwo: \(two.doMath())")

var t: TestProtocol = two
print("TestProtocol \(doMath(t))")

What the protocol extension gives you, all that it gives you, is a
different syntax for doing the exact same thing. Where your code shines
IMHO is when you want to then use the return value as a parameter to yet
another function.

two.doMath().handleResult() is far cleaner, and better expresses what is
happening, than handleResult(doMath(one))

All IMHO of course.

On Feb 16, 2016, at 9:28 PM, Jon Hoffman <hoffman.jon@gmail.com> wrote:

You are correct that if you are using the protocol type to interact with
the instance then the method defined in the protocol extension will be
called however if it is type casted to a concrete type which has a method
that overrides the method in the protocol extension then the method in the
concrete type would be called. This following code illustrates this:

protocol TestProtocol {
    var num1: Int {get set}
    var num2: Int {get set}
}

extension TestProtocol {
    func doMath() -> Int {
        return num1 + num2
    }
}

struct MyTypeOne: TestProtocol {
    var num1 = 1
    var num2 = 2
}

struct MyTypeTwo: TestProtocol {
    var num1 = 1
    var num2 = 2
    func doMath() -> Int {
        return num2 - num1
    }
}

var one = MyTypeOne()
var two = MyTypeTwo()

print("MyTypeOne: \(one.doMath())")
print("MyTypeTwo: \(two.doMath())")

var t: TestProtocol = two
print("TestProtocol \(t.doMath())")

The output from this code would be:

*MyTypeOne: 3*
*MyTypeTwo: 1*
*TestProtocol 3*

This shows that when calling the doMath() on the MyTypeTwo instance calls
the method defined in the MyTypeTwo structure however if we call the method
on the same instance but it being typecast as the protocol will call the
method in the protocol.

For the most part we would access the types though the interface provided
by the protocol however using the “is” keyword we can check if a type is an
instance of a particular concrete type or use the typecast operator to
downcast the instance. This would give us access to the method that is
defined in the concrete type. This can certainly be useful in certain
situations. I do agree that these situation should be avoided however it
is something that can be done which we can not do with global functions. I
was just trying to list some of the differences between protocol extensions
and global functions. Honestly, and this is my personal opinion, I believe
there is significant difference between protocol extensions and global
functions: avoiding the global scope, using constraints, better code
organization to name a couple, overriding, self parameter, better code
manageability just to name some of them.

Protocol Extensions are there so we can add functionality to a group of
types that conform to a specific protocol that meets any constraints
defined by the extension. This allows us to avoid duplicate code similar
to what we did with super classes in the OOP world. However with protocols
we can create very specific protocols rather than large monolithic
superclasses. Without protocol extensions we would have to revert to
creating global functions however, in my opinion once again, the protocol
extensions is a better option. That is what I was trying to get across.

Jon

On Feb 16, 2016, at 8:30 PM, Brent Royal-Gordon <brent@architechies.com> > wrote:

We can override functionality provided from a protocol extension if we
need specific functionality for a particular type.

No you can't. Protocol extension methods (that is, methods declared only
in an extension, as opposed to default implementations, which are both
declared in the protocol and defined in an extension) are statically
dispatched, so calling them on the protocol witness will always use the
extension's implementation, even if some concrete type conforming to the
protocol has a different implementation with the same name and signature.

(I've worked on a proposal in the past that would require keywords to make
this behavior clearer, but I've had trouble getting it through.)

In any case, I'm pretty sure that's what Daniel means when he says
extension methods are exactly equivalent to global functions. Sure, they
appear after a dot, have an implicit self parameter, and are scoped to a
particular type, but there's nothing dynamic about their behavior—they're
not overridable in any useful sense.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

I agree that there is other ways we can do code sharing besides
protocol extensions however as you pointed out extensions are the most
convenient way. I would also say that in my opinion protocol
extensions are also the most elegant and one of the easiest for new
programmers to learn when coming from an OOP background. Developers
coming from a functional backgrounds can still use global methods.

Well, global functions (except operators—an evil hack that I expect to
be removed someday [¹]) don't actually allow us to provide default
implementations for protocol requirements, so they're not a substitute
for protocol extensions.

While global functions do not let us provide default implementations for protocols themselves, we are able to create a global function that can perform common functionality on any instance of a type that conforms to a protocol thereby avoiding duplicating implementations in our types that conform to a protocol. Personally I am not a fan of that approach and do not believe it is a good protocol oriented approach.

To help grow POP with Swift, in my opinion, there really should be a
standard or recommended way for adding common functionality even if
some developers prefer to take a different approach.

I'm not talking about alternative approaches that are available in
Swift. I'm talking about different ways to get the basic generics
capabilities that fall out of protocol extensions, but using language
features we don't have. I agree that protocol extensions are a
beautifully elegant way to get these capabilities, but you could still
do the same kind of programming with a different mechanism that doesn't
allow for open-ended extension.

This will allow us to write books and articles about POP and show a
consistent approach. If different authors take different approaches,
it could get confusing for other developers that are trying to figure
out what POP is. To me standardizing on protocol extensions make the
most sense.

Of course; that's the way it's done in Swift. I'm trying to say that in
principle you can take a protocol-oriented approach in many different
languages and express the same kinds of ideas as we do in Swift, though
it may not be as elegant. Heck, I was doing much of this in C++ for
years, and C++ doesn't even have protocols! Of course, it's much uglier
to do so. Swift is the best language I've seen for expressing the
protocol-oriented approach. It's also protocol-oriented at its core,
using protocols for literals, looping, and bridging to Objective C.

I can see the benefits with also showing other approaches at the same
time we show protocol extensions larger print mediums like books
however having that standard approach will make it easier all the way
around.

No, I don't suggest you show other approaches. I'm just trying to
suggest that you think of what POP means separately from the language
mechanisms used to realize it.

Now it is your turn to tell me that I am taking a too narrow of a view on Protocol-Oriented programming :) After all I have said that about others, it is only fair for you to say the same thing to me when I do. You are correct I have been thinking of it only with Swift and should look at it separately from the language.

From the time I first saw your presentation I have only looked at it from a Swift point of view so it may be hard to separate them in my mind however I think it could be quite fascinating to think about it outside of language now that you mention it.

With all of the talent at Apple, you should have all that completed
next week and still have time for a paint ball tournament, right? :)

Mmm, delicious paint balls. Yum.

I'm just glad there are thoughtful and insightful authors like you out
there to pick up the thread.

Thank you for the compliment

Generics are a pretty broad subject to cover all at once, what parts
do you think matter the most when it comes to POP?

All of them, sorry ;-)

Just need to decide how to approach it because if a blog post is too long, people tend to not read it all and as you can see, I do tend to write a lot ;) even when it is not necessary.

What makes protocols in Swift different from Java interfaces (or
Objective-C protocols for that matter) is that they support static
polymorphism and generic programming.

Unless I am misunderstanding what you are saying here, Java interfaces do support generic programming: Defining Simple Generics (The Java™ Tutorials > Bonus > Generics)

···

On Mar 7, 2016, at 6:34 PM, Dave Abrahams <dabrahams@apple.com> wrote:
on Mon Mar 07 2016, Jon Hoffman <hoffman.jon-AT-gmail.com> wrote:

I do not know enough about ECS to comment any further than the
granular approach but yes I think that approach is similar to what POP
is.

Footnotes:
[¹] https://github.com/apple/swift/blob/master/test/Prototypes/GenericDispatch.swift

--
-Dave

But who better to have a discussion about "The Old Man and the Sea" with then Hemingway himself?

Jon

···

On Mar 8, 2016, at 4:49 AM, Tino Heth <2th@gmx.de> wrote:

Forty lashes with a wet noodle for you, my friend.

that's so cruel… I think it's unfair of you to join this discussion: It's like Hemingway dropping in an oral exam about "The Old Man and the Sea", starting to ask questions ;-)

Ah yes Wallacy! That’s the point I’m making.

Procedural, Functional, Modular, and Object Oriented programming are different paradigms. Languages can cater to different paradigms by making it easier to code in some than others, but the paradigm has nothing to do with the language per se. You can do OO in C with function pointers, it just requires more typing.

The point I’ve been trying to make to Jon is that POP is not a new paradigm, but it *is* a better syntax for the same paradigm. Better syntax is a great thing and deserves accolades, but don’t make it out for more than it is.

···

On Feb 17, 2016, at 9:20 AM, Wallacy <wallacyf@gmail.com> wrote:

If you go further, you will realize that Objects are only Structures with some function pointers.

The differences on structured programming and object-oriented programming can be reduced to a "syntax level" too.

POP for example encourages more use of multiple (inheritance|composition) than OO. The pattern is more important than syntax.

However I agree, Swift POP still have many limitations and almost no innovation. There are several proposed improvements to protocols that should arrive in the next versions, maybe then people start to consider POP a true paradigm. For now is just a syntax sugar for Composition over inheritance.

I do agree that there isn’t a lot of functional innovation with POP however where I would disagree is saying it is the same paradigm as OOP (or other programming paradigm). And it is OK to agree to disagree that is where good discussions can be found.

The reason that I would disagree is because how we think about the design is different. With OOP we have the single monolithic superclasses with class hierarchies. With POP, I believe the design may be closer to the Entity Component System described in Adam Eberbach’s e-mail because POP encourages a more modular or component design for our types using protocol composition and protocol inheritance.

I do agree that languages can cater to different programming paradigms. To be honest, programming paradigm basically boil down to how we architect our application and in my opinion how we architect/design our application with POP is different than OOP because we design/compose our types differently and we are no longer encouraged to use class hierarchies which is really the backbone of OOP.

Jon

···

On Feb 17, 2016, at 10:39 AM, Daniel Tartaglia <danielt1263@gmail.com> wrote:

Ah yes Wallacy! That’s the point I’m making.

Procedural, Functional, Modular, and Object Oriented programming are different paradigms. Languages can cater to different paradigms by making it easier to code in some than others, but the paradigm has nothing to do with the language per se. You can do OO in C with function pointers, it just requires more typing.

The point I’ve been trying to make to Jon is that POP is not a new paradigm, but it *is* a better syntax for the same paradigm. Better syntax is a great thing and deserves accolades, but don’t make it out for more than it is.

On Feb 17, 2016, at 9:20 AM, Wallacy <wallacyf@gmail.com <mailto:wallacyf@gmail.com>> wrote:

If you go further, you will realize that Objects are only Structures with some function pointers.

The differences on structured programming and object-oriented programming can be reduced to a "syntax level" too.

POP for example encourages more use of multiple (inheritance|composition) than OO. The pattern is more important than syntax.

However I agree, Swift POP still have many limitations and almost no innovation. There are several proposed improvements to protocols that should arrive in the next versions, maybe then people start to consider POP a true paradigm. For now is just a syntax sugar for Composition over inheritance.

I agree that there is other ways we can do code sharing besides
protocol extensions however as you pointed out extensions are the most
convenient way. I would also say that in my opinion protocol
extensions are also the most elegant and one of the easiest for new
programmers to learn when coming from an OOP background. Developers
coming from a functional backgrounds can still use global methods.

Well, global functions (except operators—an evil hack that I expect to
be removed someday [¹]) don't actually allow us to provide default
implementations for protocol requirements, so they're not a substitute
for protocol extensions.

While global functions do not let us provide default implementations for protocols themselves, we are able to create a global function that can perform common functionality on any instance of a type that conforms to a protocol thereby avoiding duplicating implementations in our types that conform to a protocol. Personally I am not a fan of that approach and do not believe it is a good protocol oriented approach.

To help grow POP with Swift, in my opinion, there really should be a
standard or recommended way for adding common functionality even if
some developers prefer to take a different approach.

I'm not talking about alternative approaches that are available in
Swift. I'm talking about different ways to get the basic generics
capabilities that fall out of protocol extensions, but using language
features we don't have. I agree that protocol extensions are a
beautifully elegant way to get these capabilities, but you could still
do the same kind of programming with a different mechanism that doesn't
allow for open-ended extension.

This will allow us to write books and articles about POP and show a
consistent approach. If different authors take different approaches,
it could get confusing for other developers that are trying to figure
out what POP is. To me standardizing on protocol extensions make the
most sense.

Of course; that's the way it's done in Swift. I'm trying to say that in
principle you can take a protocol-oriented approach in many different
languages and express the same kinds of ideas as we do in Swift, though
it may not be as elegant. Heck, I was doing much of this in C++ for
years, and C++ doesn't even have protocols! Of course, it's much uglier
to do so. Swift is the best language I've seen for expressing the
protocol-oriented approach. It's also protocol-oriented at its core,
using protocols for literals, looping, and bridging to Objective C.

I can see the benefits with also showing other approaches at the same
time we show protocol extensions larger print mediums like books
however having that standard approach will make it easier all the way
around.

No, I don't suggest you show other approaches. I'm just trying to
suggest that you think of what POP means separately from the language
mechanisms used to realize it.

Now it is your turn to tell me that I am taking a too narrow of a view on Protocol-Oriented programming :) After all I have said that about others, it is only fair for you to say the same thing to me when I do. You are correct I have been thinking of it only with Swift and should look at it separately from the language.

From the time I first saw your presentation I have only looked at it from a Swift point of view so it may be hard to separate them in my mind however I think it could be quite fascinating to think about it outside of language now that you mention it.

With all of the talent at Apple, you should have all that completed
next week and still have time for a paint ball tournament, right? :)

Mmm, delicious paint balls. Yum.

I'm just glad there are thoughtful and insightful authors like you out
there to pick up the thread.

Thank you for the compliment

Generics are a pretty broad subject to cover all at once, what parts
do you think matter the most when it comes to POP?

All of them, sorry ;-)

Just need to decide how to approach it because if a blog post is too long, people tend to not read it all and as you can see, I do tend to write a lot ;) even when it is not necessary.

What makes protocols in Swift different from Java interfaces (or
Objective-C protocols for that matter) is that they support static
polymorphism and generic programming.

Unless I am misunderstanding what you are saying here, Java interfaces do support generic programming: Defining Simple Generics (The Java™ Tutorials > Bonus > Generics)

I think “static” is the operative word there.

···

On Mar 7, 2016, at 6:48 PM, Jon Hoffman via swift-users <swift-users@swift.org> wrote:

On Mar 7, 2016, at 6:34 PM, Dave Abrahams <dabrahams@apple.com <mailto:dabrahams@apple.com>> wrote:
on Mon Mar 07 2016, Jon Hoffman <hoffman.jon-AT-gmail.com <http://hoffman.jon-at-gmail.com/&gt;&gt; wrote:

I do not know enough about ECS to comment any further than the
granular approach but yes I think that approach is similar to what POP
is.

Footnotes:
[¹] https://github.com/apple/swift/blob/master/test/Prototypes/GenericDispatch.swift

--
-Dave

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Actually, “generic programming” are the operative words. I don't mean,
“does the language have a feature that it calls ‘generics?’”, I mean “does
it support the discipline of generic programming?”

See:

  http://www.osl.iu.edu/publications/prints/2005/garcia05:_extended_comparing05.pdf
  From Mathematics to Generic Programming - Alexander A. Stepanov, Daniel E. Rose - Google Books

···

on Tue Mar 08 2016, Michael Ilseman <milseman-AT-apple.com> wrote:

What makes protocols in Swift different from Java interfaces (or
Objective-C protocols for that matter) is that they support static
polymorphism and generic programming.

Unless I am misunderstanding what you are saying here, Java
interfaces do support generic programming:
Defining Simple Generics (The Java™ Tutorials > Bonus > Generics)
<JDK 21 Documentation - Home;

I think “static” is the operative word there.

--
-Dave

What makes protocols in Swift different from Java interfaces (or
Objective-C protocols for that matter) is that they support static
polymorphism and generic programming.

Unless I am misunderstanding what you are saying here, Java
interfaces do support generic programming:
Defining Simple Generics (The Java™ Tutorials > Bonus > Generics)
<JDK 21 Documentation - Home;

I think “static” is the operative word there.

Actually, “generic programming” are the operative words. I don't mean,
“does the language have a feature that it calls ‘generics?’”, I mean “does
it support the discipline of generic programming?”

See:

http://www.osl.iu.edu/publications/prints/2005/garcia05:_extended_comparing05.pdf
From Mathematics to Generic Programming - Alexander A. Stepanov, Daniel E. Rose - Google Books

I have always looked at Generics from a Java point of view because that is the language in which I started really using them with my code. I did start reading the document during my daughter’s TaeKwonDo class tonight and it does seem pretty interesting. I will have to make time to read it in the next few days. Page 4 of the document has a chart that shows how the different languages compare. I can see, just from the top of my head that Swift has better support than some of the languages however not as well as Haskell or SML. How do you see Swift currently comparing to the other languages and how do you see it comparing in the future?

···

On Mar 8, 2016, at 2:38 PM, Dave Abrahams <dabrahams@apple.com> wrote:
on Tue Mar 08 2016, Michael Ilseman <milseman-AT-apple.com> wrote:

--
-Dave