Changing behavior of a released object
I was working on some upgrades to my rm.slice MXJ I noticed there is a mistake in my original version of the algorithm. My first instinct was to fix this but leave behind the option to activate legacy mode via an attribute. I then realized that even though the correct algorithm would be better, this may change behavior of existing patches for the few users of this object.
I guess I could have two behaviors in the object with the original as default and the improved version selectable via an attribute, but this would put new users of the object at a disadvantage if they don’t realize to try the improved algorithm by setting the attribute.
So is my best option just to keep the current object as is and release a new rm.slice2 or something? Anyone have any other suggestions for this type of issue?
if it’s an mxj object then it will only affect those who replace the old .java and .class files with the new ones– if they are consciously replacing the files, then they would be aware of the differences, and presumably repatch accordingly. So I would keep the original name and include a readme text file with the distiribution to explain the ‘silent’ update (also incl a modified help file which also explains the difference). And modify the code so the default algorithm is the better one, and ignore (don’t include) the old algorithm. I guess that’s against best practise regarding pure java but with max-java I believe it would be acceptable given the context and relatively small user base.
It is distributed in a jar, but I see your point. Would you feel the same if it was a external object written in C vs Java? Or for an abstraction? Or a Gen patch? The question came up for me for an MXJ object, but stands for Max object/abstraction/gen development in general. I remember at the Cycling ’74 Expo in New York a couple years ago quite a few questions about the odd behavior the arguments/etc of a few of the standard Max was answered with: so we don’t break old patches.
I was originally planning to handle it how you propose, but when I release this object I am also going to make it available as part of a larger library available in a single jar. Other collision issues aside, this made me start thinking such an approach may not work as well as it seems.
Even though I think there are only about 10-15 people using this object (maybe I’m wrong!), I’m flattered when other people find my code useful and I don’t want to be a jerk and break their patch.
Any other votes?
P.S.: I began distributing this to the public about 2 years ago, and to some friends 2 years before that if this plays into anyone’s opinion.
In general I would never change existing behavior, but rather add an option or attribute for switching to the new behavior. For any existing object there is an unknown and constantly increasing number of patches using that object. Nobody is going to update all those patches, no matter how much you beg and plead, and if a patch stops working correctly, you’ll get the blame.
That said: consider exactly in what ways your proposed change to behavior will actually effect patches. For instance, if your "fix" is only going to change behavior in relatively exotic configurations (and the old behavior was in some way clearly "wrong" or "buggy" in those situations), there is a reasonable chance that users will actually be happy when the behavior of their patches is changed for the better.
This may not be a decision to make lightly. (And what Nicolas said about documenting and communicating the change.)
Thanks for your feedback everyone.
Even sticking to factory objects is no guarantee of ad vitam aeternam. There is a significant number of objects from the earlier (official) Max releases that have eventually been orphaned. Just recently I was revisiting a performance patch that made extensive use of the [graphic] & friends objects.
Yeah, sure, Jitter is much cooler and can do much more, but [graphic] could do some quite useful stuff with a small fraction of the resources. Basically, almost anything I did in Max 3&4 needs to be re-written from scratch. Ironically, I have a number of Third Party Objects with longer life cycles.