swift-users Digest, Vol 3, Issue 15


(Daniel Tartaglia) #1

I have to say John that I am not a fan of your OOP code. I would have written the OOP code very much like you wrote the POP version using the Strategy pattern.

[Animal]<*>--->[Mode]
                  ^

···

           +------+------+
           > > >
        [Land] [Sea] [Air]
     
(View the above with a mono-spaced font.)

In essence, I see no difference. There may be a difference, but I don’t think your example presents one.

On Feb 15, 2016, at 1:00 PM, swift-users-request@swift.org wrote:

Date: Sun, 14 Feb 2016 18:59:05 -0500
From: Jon Hoffman <hoffman.jon@gmail.com>
To: swift-users <swift-users@swift.org>
Subject: [swift-users] Comparing POP to OOP
Message-ID: <5DA5F8F5-D645-4BF9-A0CE-1AF1DB8B3735@gmail.com>
Content-Type: text/plain; charset="utf-8"

Numerous tutorials that I have seen take a very Object-Oriented approach to the protocol-oriented programming (POP) paradigm. By this statement I mean that they tell us that with POP we should begin our design with the protocol rather than with the superclass as we did with OOP however the protocol design tends to mirror the superclass design of OOP. They also tell us that we should use extensions to add common functionality to types that conform to a protocol as we did with superclasses in OOP. While protocols and protocol extensions are arguably two of the most important concepts of POP these tutorials seem to be missing some other very important concepts.

In this post I would like to compare Protocol-Oriented design to Object-Oriented design to highlight some of the conceptual differences. You can view the blog post here: http://masteringswift.blogspot.com/2016/02/pop-and-oop.html

Jon


(Daniel Tartaglia) #2

(Reposting because I forgot to change the subject line. Hope that this is the correct thing to do.)

I have to say John that I am not a fan of your OOP code. I would have written the OOP code very much like you wrote the POP version using the Strategy pattern.

[Animal]<*>--->[Mode]
                  ^

···

           +------+------+
           > > >
        [Land] [Sea] [Air]
     
(View the above with a mono-spaced font.)

In essence, I see no difference. There may be a difference, but I don’t think your example presents one.

On Feb 15, 2016, at 1:00 PM, swift-users-request@swift.org <mailto:swift-users-request@swift.org> wrote:

Date: Sun, 14 Feb 2016 18:59:05 -0500
From: Jon Hoffman <hoffman.jon@gmail.com <mailto:hoffman.jon@gmail.com>>
To: swift-users <swift-users@swift.org <mailto:swift-users@swift.org>>
Subject: [swift-users] Comparing POP to OOP
Message-ID: <5DA5F8F5-D645-4BF9-A0CE-1AF1DB8B3735@gmail.com <mailto:5DA5F8F5-D645-4BF9-A0CE-1AF1DB8B3735@gmail.com>>
Content-Type: text/plain; charset="utf-8"

Numerous tutorials that I have seen take a very Object-Oriented approach to the protocol-oriented programming (POP) paradigm. By this statement I mean that they tell us that with POP we should begin our design with the protocol rather than with the superclass as we did with OOP however the protocol design tends to mirror the superclass design of OOP. They also tell us that we should use extensions to add common functionality to types that conform to a protocol as we did with superclasses in OOP. While protocols and protocol extensions are arguably two of the most important concepts of POP these tutorials seem to be missing some other very important concepts.

In this post I would like to compare Protocol-Oriented design to Object-Oriented design to highlight some of the conceptual differences. You can view the blog post here: http://masteringswift.blogspot.com/2016/02/pop-and-oop.html <http://masteringswift.blogspot.com/2016/02/pop-and-oop.html>

Jon


(Jon Hoffman) #3

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.

Jon

···

On Mon, Feb 15, 2016 at 1:17 PM, Daniel Tartaglia <danielt1263@gmail.com> wrote:

(Reposting because I forgot to change the subject line. Hope that this is
the correct thing to do.)

I have to say John that I am not a fan of your OOP code. I would have
written the OOP code very much like you wrote the POP version using the
Strategy pattern.

[Animal]<*>--->[Mode]
                  ^
                  >
           +------+------+
           > > >
        [Land] [Sea] [Air]

(View the above with a mono-spaced font.)

In essence, I see no difference. There may be a difference, but I don’t
think your example presents one.

On Feb 15, 2016, at 1:00 PM, swift-users-request@swift.org wrote:

Date: Sun, 14 Feb 2016 18:59:05 -0500
From: Jon Hoffman <hoffman.jon@gmail.com>
To: swift-users <swift-users@swift.org>
Subject: [swift-users] Comparing POP to OOP
Message-ID: <5DA5F8F5-D645-4BF9-A0CE-1AF1DB8B3735@gmail.com>
Content-Type: text/plain; charset="utf-8"

Numerous tutorials that I have seen take a very Object-Oriented approach
to the protocol-oriented programming (POP) paradigm. By this statement I
mean that they tell us that with POP we should begin our design with the
protocol rather than with the superclass as we did with OOP however the
protocol design tends to mirror the superclass design of OOP. They also
tell us that we should use extensions to add common functionality to types
that conform to a protocol as we did with superclasses in OOP. While
protocols and protocol extensions are arguably two of the most important
concepts of POP these tutorials seem to be missing some other very
important concepts.

In this post I would like to compare Protocol-Oriented design to
Object-Oriented design to highlight some of the conceptual differences.
You can view the blog post here:
http://masteringswift.blogspot.com/2016/02/pop-and-oop.html <
http://masteringswift.blogspot.com/2016/02/pop-and-oop.html>

Jon


(Daniel Tartaglia) #4

That’s easy to do by allowing an Animal to hold multiple modes. Yes, the code below uses a Protocol, but only as an OO interface.

let alligator = Animal()
alligator.mode.append(Land())
alligator.mode.append(Sea())

protocol Mode {
    func attack() -> Bool
    func move() -> Bool
}

class Animal {
    var modes: [Mode]
    func attack() -> Bool {
        for mode in modes {
            if mode.attack() {
                break
            }
        }
    }
}

···

On Feb 15, 2016, at 1:43 PM, Jon Hoffman <hoffman.jon@gmail.com> 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.

Jon

On Mon, Feb 15, 2016 at 1:17 PM, Daniel Tartaglia <danielt1263@gmail.com <mailto:danielt1263@gmail.com>> wrote:
(Reposting because I forgot to change the subject line. Hope that this is the correct thing to do.)

I have to say John that I am not a fan of your OOP code. I would have written the OOP code very much like you wrote the POP version using the Strategy pattern.

[Animal]<*>--->[Mode]
                  ^
                  >
           +------+------+
           > > >
        [Land] [Sea] [Air]
     
(View the above with a mono-spaced font.)

In essence, I see no difference. There may be a difference, but I don’t think your example presents one.


(Dave Abrahams) #5

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.

···

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

Jon

On Mon, Feb 15, 2016 at 1:17 PM, Daniel Tartaglia <danielt1263@gmail.com> > wrote:

(Reposting because I forgot to change the subject line. Hope that this is
the correct thing to do.)

I have to say John that I am not a fan of your OOP code. I would have
written the OOP code very much like you wrote the POP version using the
Strategy pattern.

[Animal]<*>--->[Mode]
                  ^
                  >
           +------+------+
           > > >
        [Land] [Sea] [Air]

(View the above with a mono-spaced font.)

In essence, I see no difference. There may be a difference, but I don’t
think your example presents one.

On Feb 15, 2016, at 1:00 PM, swift-users-request@swift.org wrote:

Date: Sun, 14 Feb 2016 18:59:05 -0500
From: Jon Hoffman <hoffman.jon@gmail.com>
To: swift-users <swift-users@swift.org>
Subject: [swift-users] Comparing POP to OOP
Message-ID: <5DA5F8F5-D645-4BF9-A0CE-1AF1DB8B3735@gmail.com>
Content-Type: text/plain; charset="utf-8"

Numerous tutorials that I have seen take a very Object-Oriented approach
to the protocol-oriented programming (POP) paradigm. By this statement I
mean that they tell us that with POP we should begin our design with the
protocol rather than with the superclass as we did with OOP however the
protocol design tends to mirror the superclass design of OOP. They also
tell us that we should use extensions to add common functionality to types
that conform to a protocol as we did with superclasses in OOP. While
protocols and protocol extensions are arguably two of the most important
concepts of POP these tutorials seem to be missing some other very
important concepts.

In this post I would like to compare Protocol-Oriented design to
Object-Oriented design to highlight some of the conceptual differences.
You can view the blog post here:
http://masteringswift.blogspot.com/2016/02/pop-and-oop.html <
http://masteringswift.blogspot.com/2016/02/pop-and-oop.html>

Jon

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

--
-Dave


(Jon Hoffman) #6

Sorry for the misunderstanding, I see what you are doing now, you are using
the command pattern, however I so see quite a bit of difference between
your design and my POP design. The biggest is the number of types needed
between the designs. For example, how the Lion attacks and moves on land
is different than how the Alligator attacks and moves on land therefore you
will need separate attack and movement types for each type of animal. This
means that you will need a Alligator type and to go with that Alligator
type you would need AlligatorLandAttack, AlligatorSeaAttack,
AlligatorLandMove and AlligatorSeaMove types. You would also need the Lion
type with a LionLandAttack and LionLandMove type. You would need these
separate types for each animal you create. With my POP all of this logic
would be encapsulated in a single types.

By encapsulating all of the logic into a single type your code will be
easier to manage and also less error prone. For example, in your code
there is nothing preventing a developer to accidentally adding the
LionLandAttack type to the Alligator type and since that error could occur
anyplace where an instance of the Alligator is created it could also be
hard to track down.

One of the principles of Protocol-Oriented programming is making our code
safer and easier to manage. Your code would work but I would still say
that the POP code would be much easier to manage long term and would also
be less error prone. That is my opinion and everyone will have their own.

···

On Mon, Feb 15, 2016 at 1:52 PM, Daniel Tartaglia <danielt1263@gmail.com> wrote:

That’s easy to do by allowing an Animal to hold multiple modes. Yes, the
code below uses a Protocol, but only as an OO interface.

let alligator = Animal()
alligator.mode.append(Land())
alligator.mode.append(Sea())

protocol Mode {
    func attack() -> Bool
    func move() -> Bool
}

class Animal {
    var modes: [Mode]
    func attack() -> Bool {
        for mode in modes {
            if mode.attack() {
                break
            }
        }
    }
}

On Feb 15, 2016, at 1:43 PM, Jon Hoffman <hoffman.jon@gmail.com> 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.

Jon

On Mon, Feb 15, 2016 at 1:17 PM, Daniel Tartaglia <danielt1263@gmail.com> > wrote:

(Reposting because I forgot to change the subject line. Hope that this is
the correct thing to do.)

I have to say John that I am not a fan of your OOP code. I would have
written the OOP code very much like you wrote the POP version using the
Strategy pattern.

[Animal]<*>--->[Mode]
                  ^
                  >
           +------+------+
           > > >
        [Land] [Sea] [Air]

(View the above with a mono-spaced font.)

In essence, I see no difference. There may be a difference, but I don’t
think your example presents one.


(Jon Hoffman) #7

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 and also extensions just to name two of them. 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.

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. 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

Jon

···

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:

Jon

On Mon, Feb 15, 2016 at 1:17 PM, Daniel Tartaglia <danielt1263@gmail.com> >> wrote:

(Reposting because I forgot to change the subject line. Hope that this is
the correct thing to do.)

I have to say John that I am not a fan of your OOP code. I would have
written the OOP code very much like you wrote the POP version using the
Strategy pattern.

[Animal]<*>--->[Mode]
                 ^
                 >
          +------+------+
          > > >
       [Land] [Sea] [Air]

(View the above with a mono-spaced font.)

In essence, I see no difference. There may be a difference, but I don’t
think your example presents one.

On Feb 15, 2016, at 1:00 PM, swift-users-request@swift.org wrote:

Date: Sun, 14 Feb 2016 18:59:05 -0500
From: Jon Hoffman <hoffman.jon@gmail.com>
To: swift-users <swift-users@swift.org>
Subject: [swift-users] Comparing POP to OOP
Message-ID: <5DA5F8F5-D645-4BF9-A0CE-1AF1DB8B3735@gmail.com>
Content-Type: text/plain; charset="utf-8"

Numerous tutorials that I have seen take a very Object-Oriented approach
to the protocol-oriented programming (POP) paradigm. By this statement I
mean that they tell us that with POP we should begin our design with the
protocol rather than with the superclass as we did with OOP however the
protocol design tends to mirror the superclass design of OOP. They also
tell us that we should use extensions to add common functionality to types
that conform to a protocol as we did with superclasses in OOP. While
protocols and protocol extensions are arguably two of the most important
concepts of POP these tutorials seem to be missing some other very
important concepts.

In this post I would like to compare Protocol-Oriented design to
Object-Oriented design to highlight some of the conceptual differences.
You can view the blog post here:
http://masteringswift.blogspot.com/2016/02/pop-and-oop.html <
http://masteringswift.blogspot.com/2016/02/pop-and-oop.html>

Jon

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

--
-Dave

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


(Adam Eberbach) #8

For a third approach take a look at http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/ and the following posts (5).
Entity Component Systems avoid the problem of everything migrating up into the base class and the propagation of classes by separating aspects (attributes, things the entity has) of the entity into components. The entity itself is little more than a UUID handle to the components owned by that entity. In this example an alligator has a LandComponent and a SeaComponent. A System contains the code that acts on the data contained in those components and there is a system for each kind of component, for example a LandSystem that has code to make an entity move on land. Each update the System acts on every entity that has a component matching it.

The description above is the more modern AAA-game ideal of ECS but there is disagreement about the fine points (of course!). Apple’s GameplayKit implements an older form of ECS like that developed by Scott Bilas for Dungeon Siege (http://scottbilas.com/games/dungeon-siege/) in 2003, where components have code and data.

I think this is very like the POP idea… but perhaps cleaner since the System processes, subject to the usual sync issues, can be separate threads. Adding a behaviour or a new entity is as simple as choosing the right components, aggregating them into an entity and then adding that entity to the update loop. And it doesn’t matter how many aspects you add to a class - all the code is encapsulated in the System, all the data in the Component. The POP approach is pretty good but you still wind up with a very beefy class.

···

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

Sorry for the misunderstanding, I see what you are doing now, you are using the command pattern, however I so see quite a bit of difference between your design and my POP design. The biggest is the number of types needed between the designs. For example, how the Lion attacks and moves on land is different than how the Alligator attacks and moves on land therefore you will need separate attack and movement types for each type of animal. This means that you will need a Alligator type and to go with that Alligator type you would need AlligatorLandAttack, AlligatorSeaAttack, AlligatorLandMove and AlligatorSeaMove types. You would also need the Lion type with a LionLandAttack and LionLandMove type. You would need these separate types for each animal you create. With my POP all of this logic would be encapsulated in a single types.

By encapsulating all of the logic into a single type your code will be easier to manage and also less error prone. For example, in your code there is nothing preventing a developer to accidentally adding the LionLandAttack type to the Alligator type and since that error could occur anyplace where an instance of the Alligator is created it could also be hard to track down.

One of the principles of Protocol-Oriented programming is making our code safer and easier to manage. Your code would work but I would still say that the POP code would be much easier to manage long term and would also be less error prone. That is my opinion and everyone will have their own.

On Mon, Feb 15, 2016 at 1:52 PM, Daniel Tartaglia <danielt1263@gmail.com <mailto:danielt1263@gmail.com>> wrote:
That’s easy to do by allowing an Animal to hold multiple modes. Yes, the code below uses a Protocol, but only as an OO interface.

let alligator = Animal()
alligator.mode.append(Land())
alligator.mode.append(Sea())

protocol Mode {
    func attack() -> Bool
    func move() -> Bool
}

class Animal {
    var modes: [Mode]
    func attack() -> Bool {
        for mode in modes {
            if mode.attack() {
                break
            }
        }
    }
}

On Feb 15, 2016, at 1:43 PM, Jon Hoffman <hoffman.jon@gmail.com <mailto:hoffman.jon@gmail.com>> 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.

Jon

On Mon, Feb 15, 2016 at 1:17 PM, Daniel Tartaglia <danielt1263@gmail.com <mailto:danielt1263@gmail.com>> wrote:
(Reposting because I forgot to change the subject line. Hope that this is the correct thing to do.)

I have to say John that I am not a fan of your OOP code. I would have written the OOP code very much like you wrote the POP version using the Strategy pattern.

[Animal]<*>--->[Mode]
                  ^
                  >
           +------+------+
           > > >
        [Land] [Sea] [Air]
     
(View the above with a mono-spaced font.)

In essence, I see no difference. There may be a difference, but I don’t think your example presents one.

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


(Dave Abrahams) #9

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.

···

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


(E. Maloney) #10

Interestingly, we just had a discussion about abstract classes on the Swift Evolution mailing list, and many of the people who opposed the idea of adding the feature cited the fact that Swift was a protocol-oriented programming language rather than an object-oriented programming language.

By that argument, because Swift is protocol-oriented, classes should be treated like second-class citizens that shouldn't evolve new features and don't deserve the same level of functionality provided by just about every other object-oriented programming language (aside from ObjC).

Calling Swift protocol-oriented seems to have led to a certain level of dogmatism and reflexive opposition to anything seen as object-oriented; it's protocols vs. classes.

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.

···

On Mar 5, 2016, at 5:15 PM, Jon Hoffman via swift-users <swift-users@swift.org> wrote:

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. 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


(Jon Hoffman) #11

Please excuse my ignorance on ECS. I did read though the link that you sent and also a few other sites on ECS namely https://en.wikipedia.org/wiki/Entity_component_system and http://www.gamedev.net/page/resources/_/technical/game-programming/understanding-component-entity-systems-r3013. It does appear that ECS design is a lot closer to POP then OOP based on what I read however I may not fully understand ECS.

Lets take a couple of land animals as examples. If we had a Lion, it would attack either using it’s claws or it’s teeth. An Alligator would use it’s teeth on land. A snake or spider would inject venom into it’s victim while some snakes may also squeeze the victim to death. With ECS, I believe we would have components for each type of attack. Is that correct? Then we would add the component that we need to our entity (animal).

If my description is correct, then I believe this is very similar to a POP design where we would use protocols to define the component and protocol extensions to add the functionality. This would mean we would have the BiteAttack, ClawAttack, VenomAttack and SqeezeAttack protocols with protocol extensions to add the functionality. Do I understand ECS correctly? This type of design is very good where we break all of the components down into individual types.

One advantage to using POP to implement ECS is we would define the requirements when we define the animal type. What I mean by that is we would specify what protocols the type conforms to when we define the type. This prevents developers from adding the wrong components within the code. The draw back with using POP would be the type definition could get pretty long because we would need to list all of the protocols that a type needs to conform to.

One point you made, if I understood you correctly, is that with POP we would have larger types as compared to ECS however if we use protocol extensions to add the functionality to our component types, I do not believe our individual animals types would be much bigger than the ECS ones.

Do I understand the ECS design correctly?

Jon

···

On Feb 15, 2016, at 5:51 PM, Adam Eberbach <aeberbach@me.com> wrote:

For a third approach take a look at http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/ and the following posts (5).
Entity Component Systems avoid the problem of everything migrating up into the base class and the propagation of classes by separating aspects (attributes, things the entity has) of the entity into components. The entity itself is little more than a UUID handle to the components owned by that entity. In this example an alligator has a LandComponent and a SeaComponent. A System contains the code that acts on the data contained in those components and there is a system for each kind of component, for example a LandSystem that has code to make an entity move on land. Each update the System acts on every entity that has a component matching it.

The description above is the more modern AAA-game ideal of ECS but there is disagreement about the fine points (of course!). Apple’s GameplayKit implements an older form of ECS like that developed by Scott Bilas for Dungeon Siege (http://scottbilas.com/games/dungeon-siege/) in 2003, where components have code and data.

I think this is very like the POP idea… but perhaps cleaner since the System processes, subject to the usual sync issues, can be separate threads. Adding a behaviour or a new entity is as simple as choosing the right components, aggregating them into an entity and then adding that entity to the update loop. And it doesn’t matter how many aspects you add to a class - all the code is encapsulated in the System, all the data in the Component. The POP approach is pretty good but you still wind up with a very beefy class.

On 16 Feb 2016, at 6:21 AM, Jon Hoffman via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Sorry for the misunderstanding, I see what you are doing now, you are using the command pattern, however I so see quite a bit of difference between your design and my POP design. The biggest is the number of types needed between the designs. For example, how the Lion attacks and moves on land is different than how the Alligator attacks and moves on land therefore you will need separate attack and movement types for each type of animal. This means that you will need a Alligator type and to go with that Alligator type you would need AlligatorLandAttack, AlligatorSeaAttack, AlligatorLandMove and AlligatorSeaMove types. You would also need the Lion type with a LionLandAttack and LionLandMove type. You would need these separate types for each animal you create. With my POP all of this logic would be encapsulated in a single types.

By encapsulating all of the logic into a single type your code will be easier to manage and also less error prone. For example, in your code there is nothing preventing a developer to accidentally adding the LionLandAttack type to the Alligator type and since that error could occur anyplace where an instance of the Alligator is created it could also be hard to track down.

One of the principles of Protocol-Oriented programming is making our code safer and easier to manage. Your code would work but I would still say that the POP code would be much easier to manage long term and would also be less error prone. That is my opinion and everyone will have their own.

On Mon, Feb 15, 2016 at 1:52 PM, Daniel Tartaglia <danielt1263@gmail.com <mailto:danielt1263@gmail.com>> wrote:
That’s easy to do by allowing an Animal to hold multiple modes. Yes, the code below uses a Protocol, but only as an OO interface.

let alligator = Animal()
alligator.mode.append(Land())
alligator.mode.append(Sea())

protocol Mode {
    func attack() -> Bool
    func move() -> Bool
}

class Animal {
    var modes: [Mode]
    func attack() -> Bool {
        for mode in modes {
            if mode.attack() {
                break
            }
        }
    }
}

On Feb 15, 2016, at 1:43 PM, Jon Hoffman <hoffman.jon@gmail.com <mailto:hoffman.jon@gmail.com>> 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.

Jon

On Mon, Feb 15, 2016 at 1:17 PM, Daniel Tartaglia <danielt1263@gmail.com <mailto:danielt1263@gmail.com>> wrote:
(Reposting because I forgot to change the subject line. Hope that this is the correct thing to do.)

I have to say John that I am not a fan of your OOP code. I would have written the OOP code very much like you wrote the POP version using the Strategy pattern.

[Animal]<*>--->[Mode]
                  ^
                  >
           +------+------+
           > > >
        [Land] [Sea] [Air]
     
(View the above with a mono-spaced font.)

In essence, I see no difference. There may be a difference, but I don’t think your example presents one.

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


(Daniel Tartaglia) #12

Jon,

Here’s the thing… Swift protocols are exactly equivalent to OO interfaces. Swift protocol extensions are exactly equivalent to global functions that take an object of the protocol type as a parameter.

The only difference is in some syntactic sugar.

···

On Feb 15, 2016, at 8:13 PM, Jon Hoffman <hoffman.jon@gmail.com> wrote:

Please excuse my ignorance on ECS. I did read though the link that you sent and also a few other sites on ECS namely https://en.wikipedia.org/wiki/Entity_component_system and http://www.gamedev.net/page/resources/_/technical/game-programming/understanding-component-entity-systems-r3013. It does appear that ECS design is a lot closer to POP then OOP based on what I read however I may not fully understand ECS.

Lets take a couple of land animals as examples. If we had a Lion, it would attack either using it’s claws or it’s teeth. An Alligator would use it’s teeth on land. A snake or spider would inject venom into it’s victim while some snakes may also squeeze the victim to death. With ECS, I believe we would have components for each type of attack. Is that correct? Then we would add the component that we need to our entity (animal).

If my description is correct, then I believe this is very similar to a POP design where we would use protocols to define the component and protocol extensions to add the functionality. This would mean we would have the BiteAttack, ClawAttack, VenomAttack and SqeezeAttack protocols with protocol extensions to add the functionality. Do I understand ECS correctly? This type of design is very good where we break all of the components down into individual types.

One advantage to using POP to implement ECS is we would define the requirements when we define the animal type. What I mean by that is we would specify what protocols the type conforms to when we define the type. This prevents developers from adding the wrong components within the code. The draw back with using POP would be the type definition could get pretty long because we would need to list all of the protocols that a type needs to conform to.

One point you made, if I understood you correctly, is that with POP we would have larger types as compared to ECS however if we use protocol extensions to add the functionality to our component types, I do not believe our individual animals types would be much bigger than the ECS ones.

Do I understand the ECS design correctly?

Jon

On Feb 15, 2016, at 5:51 PM, Adam Eberbach <aeberbach@me.com <mailto:aeberbach@me.com>> wrote:

For a third approach take a look at http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/ and the following posts (5).
Entity Component Systems avoid the problem of everything migrating up into the base class and the propagation of classes by separating aspects (attributes, things the entity has) of the entity into components. The entity itself is little more than a UUID handle to the components owned by that entity. In this example an alligator has a LandComponent and a SeaComponent. A System contains the code that acts on the data contained in those components and there is a system for each kind of component, for example a LandSystem that has code to make an entity move on land. Each update the System acts on every entity that has a component matching it.

The description above is the more modern AAA-game ideal of ECS but there is disagreement about the fine points (of course!). Apple’s GameplayKit implements an older form of ECS like that developed by Scott Bilas for Dungeon Siege (http://scottbilas.com/games/dungeon-siege/) in 2003, where components have code and data.

I think this is very like the POP idea… but perhaps cleaner since the System processes, subject to the usual sync issues, can be separate threads. Adding a behaviour or a new entity is as simple as choosing the right components, aggregating them into an entity and then adding that entity to the update loop. And it doesn’t matter how many aspects you add to a class - all the code is encapsulated in the System, all the data in the Component. The POP approach is pretty good but you still wind up with a very beefy class.

On 16 Feb 2016, at 6:21 AM, Jon Hoffman via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Sorry for the misunderstanding, I see what you are doing now, you are using the command pattern, however I so see quite a bit of difference between your design and my POP design. The biggest is the number of types needed between the designs. For example, how the Lion attacks and moves on land is different than how the Alligator attacks and moves on land therefore you will need separate attack and movement types for each type of animal. This means that you will need a Alligator type and to go with that Alligator type you would need AlligatorLandAttack, AlligatorSeaAttack, AlligatorLandMove and AlligatorSeaMove types. You would also need the Lion type with a LionLandAttack and LionLandMove type. You would need these separate types for each animal you create. With my POP all of this logic would be encapsulated in a single types.

By encapsulating all of the logic into a single type your code will be easier to manage and also less error prone. For example, in your code there is nothing preventing a developer to accidentally adding the LionLandAttack type to the Alligator type and since that error could occur anyplace where an instance of the Alligator is created it could also be hard to track down.

One of the principles of Protocol-Oriented programming is making our code safer and easier to manage. Your code would work but I would still say that the POP code would be much easier to manage long term and would also be less error prone. That is my opinion and everyone will have their own.

On Mon, Feb 15, 2016 at 1:52 PM, Daniel Tartaglia <danielt1263@gmail.com <mailto:danielt1263@gmail.com>> wrote:
That’s easy to do by allowing an Animal to hold multiple modes. Yes, the code below uses a Protocol, but only as an OO interface.

let alligator = Animal()
alligator.mode.append(Land())
alligator.mode.append(Sea())

protocol Mode {
    func attack() -> Bool
    func move() -> Bool
}

class Animal {
    var modes: [Mode]
    func attack() -> Bool {
        for mode in modes {
            if mode.attack() {
                break
            }
        }
    }
}

On Feb 15, 2016, at 1:43 PM, Jon Hoffman <hoffman.jon@gmail.com <mailto:hoffman.jon@gmail.com>> 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.

Jon

On Mon, Feb 15, 2016 at 1:17 PM, Daniel Tartaglia <danielt1263@gmail.com <mailto:danielt1263@gmail.com>> wrote:
(Reposting because I forgot to change the subject line. Hope that this is the correct thing to do.)

I have to say John that I am not a fan of your OOP code. I would have written the OOP code very much like you wrote the POP version using the Strategy pattern.

[Animal]<*>--->[Mode]
                  ^
                  >
           +------+------+
           > > >
        [Land] [Sea] [Air]
     
(View the above with a mono-spaced font.)

In essence, I see no difference. There may be a difference, but I don’t think your example presents one.

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


(Jon Hoffman) #13

I would agree with you that protocols in swift are equivalent to interfaces
in other languages. However exactly equivalent may not be totally
correct. How interfaces are used in an OSGi bundles for dependencies with
Java is different than how we use protocols in Swift. You are correct that
the underlying philosophy between interfaces and protocols are equivalent,
how they are used in the various languages and programming paradigm can be
significantly different.

Where I respectfully disagree with your statement is when you say that
protocol extensions are exactly equivalent to global functions that take an
object of the protocol type as a parameter. The most obvious difference is
global functions reside in the global scope while protocol extensions are
part of the type instance. We can override functionality provided from a
protocol extension if we need specific functionality for a particular
type. We can also use constraints with protocol extensions to limit the
types that will receive the functionality from an extensions. There is
just so many ways that make protocol extensions superior to global
functions that even if you do not agree with the Protocol Oriented
programming paradigm, I would recommend taking another look at protocol
extensions.

Jon

···

On Tue, Feb 16, 2016 at 7:36 AM, Daniel Tartaglia <danielt1263@gmail.com> wrote:

Jon,

Here’s the thing… Swift protocols are exactly equivalent to OO interfaces.
Swift protocol extensions are exactly equivalent to global functions that
take an object of the protocol type as a parameter.

The only difference is in some syntactic sugar.

On Feb 15, 2016, at 8:13 PM, Jon Hoffman <hoffman.jon@gmail.com> wrote:

Please excuse my ignorance on ECS. I did read though the link that you
sent and also a few other sites on ECS namely
https://en.wikipedia.org/wiki/Entity_component_system and
http://www.gamedev.net/page/resources/_/technical/game-programming/understanding-component-entity-systems-r3013.
It does appear that ECS design is a lot closer to POP then OOP based on
what I read however I may not fully understand ECS.

Lets take a couple of land animals as examples. If we had a Lion, it
would attack either using it’s claws or it’s teeth. An Alligator would use
it’s teeth on land. A snake or spider would inject venom into it’s victim
while some snakes may also squeeze the victim to death. With ECS, I
believe we would have components for each type of attack. Is that
correct? Then we would add the component that we need to our entity
(animal).

If my description is correct, then I believe this is very similar to a POP
design where we would use protocols to define the component and protocol
extensions to add the functionality. This would mean we would have the
BiteAttack, ClawAttack, VenomAttack and SqeezeAttack protocols with
protocol extensions to add the functionality. Do I understand ECS
correctly? This type of design is very good where we break all of the
components down into individual types.

One advantage to using POP to implement ECS is we would define the
requirements when we define the animal type. What I mean by that is we
would specify what protocols the type conforms to when we define the type.
This prevents developers from adding the wrong components within the
code. The draw back with using POP would be the type definition could get
pretty long because we would need to list all of the protocols that a type
needs to conform to.

One point you made, if I understood you correctly, is that with POP we
would have larger types as compared to ECS however if we use protocol
extensions to add the functionality to our component types, I do not
believe our individual animals types would be much bigger than the ECS
ones.

Do I understand the ECS design correctly?
Jon

On Feb 15, 2016, at 5:51 PM, Adam Eberbach <aeberbach@me.com> wrote:

For a third approach take a look at
http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/ and
the following posts (5).
Entity Component Systems avoid the problem of everything migrating up into
the base class and the propagation of classes by separating aspects
(attributes, things the entity has) of the entity into components. The
entity itself is little more than a UUID handle to the components owned by
that entity. In this example an alligator has a LandComponent and a
SeaComponent. A System contains the code that acts on the data contained in
those components and there is a system for each kind of component, for
example a LandSystem that has code to make an entity move on land. Each
update the System acts on every entity that has a component matching it.

The description above is the more modern AAA-game ideal of ECS but there
is disagreement about the fine points (of course!). Apple’s GameplayKit
implements an older form of ECS like that developed by Scott Bilas for
Dungeon Siege (http://scottbilas.com/games/dungeon-siege/) in 2003, where
components have code and data.

I think this is very like the POP idea… but perhaps cleaner since the
System processes, subject to the usual sync issues, can be separate
threads. Adding a behaviour or a new entity is as simple as choosing the
right components, aggregating them into an entity and then adding that
entity to the update loop. And it doesn’t matter how many aspects you add
to a class - all the code is encapsulated in the System, all the data in
the Component. The POP approach is pretty good but you still wind up with a
very beefy class.

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

Sorry for the misunderstanding, I see what you are doing now, you are
using the command pattern, however I so see quite a bit of difference
between your design and my POP design. The biggest is the number of
types needed between the designs. For example, how the Lion attacks and
moves on land is different than how the Alligator attacks and moves on land
therefore you will need separate attack and movement types for each type of
animal. This means that you will need a Alligator type and to go with
that Alligator type you would need AlligatorLandAttack, AlligatorSeaAttack,
AlligatorLandMove and AlligatorSeaMove types. You would also need the
Lion type with a LionLandAttack and LionLandMove type. You would need
these separate types for each animal you create. With my POP all of this
logic would be encapsulated in a single types.

By encapsulating all of the logic into a single type your code will be
easier to manage and also less error prone. For example, in your code
there is nothing preventing a developer to accidentally adding the
LionLandAttack type to the Alligator type and since that error could occur
anyplace where an instance of the Alligator is created it could also be
hard to track down.

One of the principles of Protocol-Oriented programming is making our code
safer and easier to manage. Your code would work but I would still say
that the POP code would be much easier to manage long term and would also
be less error prone. That is my opinion and everyone will have their own.

On Mon, Feb 15, 2016 at 1:52 PM, Daniel Tartaglia <danielt1263@gmail.com> > wrote:

That’s easy to do by allowing an Animal to hold multiple modes. Yes, the
code below uses a Protocol, but only as an OO interface.

let alligator = Animal()
alligator.mode.append(Land())
alligator.mode.append(Sea())

protocol Mode {
    func attack() -> Bool
    func move() -> Bool
}

class Animal {
    var modes: [Mode]
    func attack() -> Bool {
        for mode in modes {
            if mode.attack() {
                break
            }
        }
    }
}

On Feb 15, 2016, at 1:43 PM, Jon Hoffman <hoffman.jon@gmail.com> 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.

Jon

On Mon, Feb 15, 2016 at 1:17 PM, Daniel Tartaglia <danielt1263@gmail.com> >> wrote:

(Reposting because I forgot to change the subject line. Hope that this
is the correct thing to do.)

I have to say John that I am not a fan of your OOP code. I would have
written the OOP code very much like you wrote the POP version using the
Strategy pattern.

[Animal]<*>--->[Mode]
                  ^
                  >
           +------+------+
           > > >
        [Land] [Sea] [Air]

(View the above with a mono-spaced font.)

In essence, I see no difference. There may be a difference, but I don’t
think your example presents one.

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


(Brent Royal-Gordon) #14

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


(Dave Abrahams) #15

Jon,

Here’s the thing… Swift protocols are exactly equivalent to OO
interfaces.

That's true of Objective-C protocols, but not of Swift protocols. The
only way it can be said of Swift protocols is if you never use them with
value types and you restrict yourself to the dynamically-dispatched
subset of what they provide (i.e. no self requirements or associated
types).

Swift protocol extensions are exactly equivalent to global functions
that take an object of the protocol type as a parameter.

The only difference is in some syntactic sugar.

Also untrue. A constrained protocol extension can conditionally fulfill
a protocol requirement for a whole category of conforming types. You
can't do that with global functions (except operators, and it's a
horrible hack that we'll remove one day).

···

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

On Feb 15, 2016, at 8:13 PM, Jon Hoffman <hoffman.jon@gmail.com> wrote:

Please excuse my ignorance on ECS. I did read though the link that
you sent and also a few other sites on ECS namely
https://en.wikipedia.org/wiki/Entity_component_system
<https://en.wikipedia.org/wiki/Entity_component_system> and
http://www.gamedev.net/page/resources//technical/game-programming/understanding-component-entity-systems-r3013
<http://www.gamedev.net/page/resources/
/technical/game-programming/understanding-component-entity-systems-r3013>.
It does appear that ECS design is a lot closer to POP then OOP based
on what I read however I may not fully understand ECS.

Lets take a couple of land animals as examples. If we had a Lion,
it would attack either using it’s claws or it’s teeth. An Alligator
would use it’s teeth on land. A snake or spider would inject venom
into it’s victim while some snakes may also squeeze the victim to
death. With ECS, I believe we would have components for each type
of attack. Is that correct? Then we would add the component that
we need to our entity (animal).

If my description is correct, then I believe this is very similar to
a POP design where we would use protocols to define the component
and protocol extensions to add the functionality. This would mean
we would have the BiteAttack, ClawAttack, VenomAttack and
SqeezeAttack protocols with protocol extensions to add the
functionality. Do I understand ECS correctly? This type of design
is very good where we break all of the components down into
individual types.

One advantage to using POP to implement ECS is we would define the
requirements when we define the animal type. What I mean by that is
we would specify what protocols the type conforms to when we define
the type. This prevents developers from adding the wrong components
within the code. The draw back with using POP would be the type
definition could get pretty long because we would need to list all
of the protocols that a type needs to conform to.

One point you made, if I understood you correctly, is that with POP
we would have larger types as compared to ECS however if we use
protocol extensions to add the functionality to our component types,
I do not believe our individual animals types would be much bigger
than the ECS ones.

Do I understand the ECS design correctly?

Jon

On Feb 15, 2016, at 5:51 PM, Adam Eberbach <aeberbach@me.com <mailto:aeberbach@me.com>> wrote:

For a third approach take a look at
http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/
<http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/>
and the following posts (5).
Entity Component Systems avoid the problem of everything migrating
up into the base class and the propagation of classes by separating
aspects (attributes, things the entity has) of the entity into
components. The entity itself is little more than a UUID handle to
the components owned by that entity. In this example an alligator
has a LandComponent and a SeaComponent. A System contains the code
that acts on the data contained in those components and there is a
system for each kind of component, for example a LandSystem that
has code to make an entity move on land. Each update the System
acts on every entity that has a component matching it.

The description above is the more modern AAA-game ideal of ECS but
there is disagreement about the fine points (of course!). Apple’s
GameplayKit implements an older form of ECS like that developed by
Scott Bilas for Dungeon Siege
(http://scottbilas.com/games/dungeon-siege/
<http://scottbilas.com/games/dungeon-siege/>) in 2003, where
components have code and data.

I think this is very like the POP idea… but perhaps cleaner since
the System processes, subject to the usual sync issues, can be
separate threads. Adding a behaviour or a new entity is as simple
as choosing the right components, aggregating them into an entity
and then adding that entity to the update loop. And it doesn’t
matter how many aspects you add to a class - all the code is
encapsulated in the System, all the data in the Component. The POP
approach is pretty good but you still wind up with a very beefy
class.

On 16 Feb 2016, at 6:21 AM, Jon Hoffman via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Sorry for the misunderstanding, I see what you are doing now, you are using the command pattern, however I so see quite a bit of difference between your design and my POP design. The biggest is the number of types needed between the designs. For example, how the Lion attacks and moves on land is different than how the Alligator attacks and moves on land therefore you will need separate attack and movement types for each type of animal. This means that you will need a Alligator type and to go with that Alligator type you would need AlligatorLandAttack, AlligatorSeaAttack, AlligatorLandMove and AlligatorSeaMove types. You would also need the Lion type with a LionLandAttack and LionLandMove type. You would need these separate types for each animal you create. With my POP all of this logic would be encapsulated in a single types.

By encapsulating all of the logic into a single type your code will be easier to manage and also less error prone. For example, in your code there is nothing preventing a developer to accidentally adding the LionLandAttack type to the Alligator type and since that error could occur anyplace where an instance of the Alligator is created it could also be hard to track down.

One of the principles of Protocol-Oriented programming is making our code safer and easier to manage. Your code would work but I would still say that the POP code would be much easier to manage long term and would also be less error prone. That is my opinion and everyone will have their own.

On Mon, Feb 15, 2016 at 1:52 PM, Daniel Tartaglia <danielt1263@gmail.com <mailto:danielt1263@gmail.com>> wrote:
That’s easy to do by allowing an Animal to hold multiple modes. Yes, the code below uses a Protocol, but only as an OO interface.

let alligator = Animal()
alligator.mode.append(Land())
alligator.mode.append(Sea())

protocol Mode {
    func attack() -> Bool
    func move() -> Bool
}

class Animal {
    var modes: [Mode]
    func attack() -> Bool {
        for mode in modes {
            if mode.attack() {
                break
            }
        }
    }
}

On Feb 15, 2016, at 1:43 PM, Jon Hoffman <hoffman.jon@gmail.com <mailto:hoffman.jon@gmail.com>> 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.

Jon

On Mon, Feb 15, 2016 at 1:17 PM, Daniel Tartaglia <danielt1263@gmail.com <mailto:danielt1263@gmail.com>> wrote:
(Reposting because I forgot to change the subject line. Hope that this is the correct thing to do.)

I have to say John that I am not a fan of your OOP code. I would have written the OOP code very much like you wrote the POP version using the Strategy pattern.

[Animal]<*>--->[Mode]
                  ^
                  >
           +------+------+
           > > >
        [Land] [Sea] [Air]
     
(View the above with a mono-spaced font.)

In essence, I see no difference. There may be a difference, but I don’t think your example presents one.

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

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

--
-Dave


(Jon Hoffman) #16

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. Also sorry for the long e-mails 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.

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

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?

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. 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.

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.

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 Abrahams) #17

For every good idea, there's always some fraction of the community that
will take it too far. Swift is more protocol-oriented than
object-oriented at its core, but Swift is a multiparadigm language.

···

on Wed Mar 09 2016, Evan Maloney <emaloney-AT-gilt.com> wrote:

On Mar 5, 2016, at 5:15 PM, Jon Hoffman via swift-users <swift-users@swift.org> wrote:

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. 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

Interestingly, we just had a discussion about abstract classes on the
Swift Evolution mailing list, and many of the people who opposed the
idea of adding the feature cited the fact that Swift was a
protocol-oriented programming language rather than an object-oriented
programming language.

By that argument, because Swift is protocol-oriented, classes should
be treated like second-class citizens that shouldn't evolve new
features and don't deserve the same level of functionality provided by
just about every other object-oriented programming language (aside
from ObjC).

Calling Swift protocol-oriented seems to have led to a certain level
of dogmatism and reflexive opposition to anything seen as
object-oriented; it's protocols vs. classes.

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.

--
-Dave


(E. Maloney) #18

Don't get me wrong -- I love protocol-oriented programming. I thought your "Crusty" WWDC talk was quite illuminating (and funny). But I still wish Swift had abstract classes! :wink:

···

On Mar 9, 2016, at 5:10 PM, Dave Abrahams <dabrahams@apple.com> wrote:

on Wed Mar 09 2016, Evan Maloney <emaloney-AT-gilt.com> wrote:

On Mar 5, 2016, at 5:15 PM, Jon Hoffman via swift-users <swift-users@swift.org> wrote:

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. 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

Interestingly, we just had a discussion about abstract classes on the
Swift Evolution mailing list, and many of the people who opposed the
idea of adding the feature cited the fact that Swift was a
protocol-oriented programming language rather than an object-oriented
programming language.

By that argument, because Swift is protocol-oriented, classes should
be treated like second-class citizens that shouldn't evolve new
features and don't deserve the same level of functionality provided by
just about every other object-oriented programming language (aside
from ObjC).

Calling Swift protocol-oriented seems to have led to a certain level
of dogmatism and reflexive opposition to anything seen as
object-oriented; it's protocols vs. classes.

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.

For every good idea, there's always some fraction of the community that
will take it too far. Swift is more protocol-oriented than
object-oriented at its core, but Swift is a multiparadigm language.

--
-Dave


(Shawn Erickson) #19

You can count me in that minority :slight_smile:

···

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.


(Jon Hoffman) #20

I am not a big fan of abstract classes however that is a personal opinion. Being able to use the paradigm that you want to use with Swift is one of the best features.
Jon

···

On Mar 9, 2016, at 3:15 PM, Evan Maloney <emaloney@gilt.com> wrote:

On Mar 5, 2016, at 5:15 PM, Jon Hoffman via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

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. 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

Interestingly, we just had a discussion about abstract classes on the Swift Evolution mailing list, and many of the people who opposed the idea of adding the feature cited the fact that Swift was a protocol-oriented programming language rather than an object-oriented programming language.

By that argument, because Swift is protocol-oriented, classes should be treated like second-class citizens that shouldn't evolve new features and don't deserve the same level of functionality provided by just about every other object-oriented programming language (aside from ObjC).

Calling Swift protocol-oriented seems to have led to a certain level of dogmatism and reflexive opposition to anything seen as object-oriented; it's protocols vs. classes.

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.