on Tue Aug 02 2016, Rick Mann <rmann-AT-latencyzero.com> wrote: >> On Aug 2, 2016, at 13:07 , Dave Abrahams via swift-users >> <swift-users@swift.org> wrote: >> >> >> on Mon Aug 01 2016, Rick Mann <swift-users-AT-swift.org> wrote: >> > >>>> On Aug 1, 2016, at 19:18 , Jack Lawrence <ja...@apple.com> wrote: >>>> >>>> Jens: Why? There are significant benefits to value semantics for >>>> this type of problem, for the reasons laid out in the WWDC >>>> videos. It would be helpful to know why you disagree in this >>>> case—maybe there are solutions to the issues you’re thinking of. >>>> >>>> Rick: I’d think that value semantics would be the right choice >>>> here. When you do a mutation, you would copy the state of the entire >>>> diagram. It should be efficient via COW, but if not you can >>>> implement you own more fine-grained COW types with >>>> isUniquelyReferenced(). This would allow you to easily support >>>> things like undo. >>> >>> The more I consider this, the more I think value semantics won't work >>> for me. I think, to take advantage of the easy undo feature, my entire >>> model *must* be implemented with value semantics. >> >> That certainly helps. You could introduce an explicit copy operation >> to get around the use of classes, but that can get very messy. >> >>> But my model has implicit reference semantics: multiple instances of a >>> part can share a PartDefinition; it is intended that if the >>> PartDefinition changes, all the referencing instances get the >>> change. >> >> That is definitely a reference. However, there are lots of ways to >> represent references such that the entire model still has value >> semantics. Reference semantics, in the broadest sense, are everywhere: >> as soon as you have an array and an integer, you have reference >> semantics. The problem with using classes is that they introduce >> reference semantics *implicitly* and *prolifically*. >> >> So, for example, if you are implementing a model and you want to >> represent a selection as a separate data structure, then you'll need to >> give every selectable element some kind of id, so you can store the ids >> there. One way to do that is to store all your elements in an array in >> your model, and use the index into the array as the id. Then when one >> element needs to refer to another element, it stores the ID of that >> element. >> >> [Aside: one of the simplest and most efficient representations of a >> generalized graph structure is `[[Int]]`, which has value semantics. >> Each element of the outer array corresponds to a vertex, and each >> element an inner array represents the target of that vertex's outgoing >> edges] >> >> The most obvious thing you don't get from this kind of arrangement is >> automatic lifetime management: an element doesn't disappear just because >> you've stopped referring to it. Whether that's appropriate for your >> application or not is a question for you to answer. >> >> You can selectively recreate as much of the implicit behavior of classes >> as you like, e.g. storing reference counts to recreate automatic >> lifetime management and/or threading a free list through the array to >> maintain ID stability, but of course at some point it becomes silly. >> >> Where your particular application falls in this spectrum is for you to >> say. The fact that there's a component of reference semantics in your >> model doesn't mean you can't use value types, and the fact that using >> value types has some awesome benefits doesn't mean you can't use >> classes. Weigh the tradeoffs and make an informed choice. >> >>> There are additional situations in which reference semantics are at >>> play, as well: a PartDefinition can have one or more labels, but each >>> instance can specify the relative location of the label for that >>> instance. So, there is struct that contains a position and a reference >>> to the label in the PartDefinition. But if the contents of the label >>> changes, all the instances need to see that change. >>> >>> I don't think I get to take advantage of value semantics, and it makes >>> me wonder if any typical, non-trivial model's object graph really has >>> no reference semantics. >> >> Some do, but many-to-one relationships are an important concept, and >> many applications need to represent them somehow. I've personally found >> that most such relationships are best expressed explicitly, which allows >> me to preserve value semantics of the whole system. YMMV, of course. > > Hmm. Seems there's a need in the language for expressing exactly this > kind of thing: explicit reference semantics.
That's called “class.” ;-) But more seriously, if you have ideas, I'm all ears (on the -evolution list, of course). > I sure don't want to manage that all on my own. It's not that big a deal; you manage it all on your own every time you use an array, dictionary, or set, with indices or keys playing the role of references. Cheers, -- -Dave _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users