> 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. I sure don't want to manage that all on my own. -- Rick Mann rm...@latencyzero.com _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users