Kenny Tilton ktilton@nyc.rr.com On Sun, 06 Mar 2005 15:55:29 -0500, Kenny Tilton ktilton@nyc.rr.com wrote:
Not sure what code you are referring to. I would not have the slider set the zoom, I would give the zoom a rule which watched the slider value, which would just go from zero to one. When the new requirement came along I would simply have the zoom rule look at the slider /and/ the sample rate. Seems easy enough to me, and more self-documenting than the approach you described. If the zoom value is coming out wrong, I like knowing without doubt exactly where to look. Hell, in the inspector I can even look at the code, which for debugging purposes I store in symbolic form in the Cell for those cases where a slot gets different rules for different instances so often that it is painful to work out which rule applies to some instance I am debugging.
Now this I have to disagree with, from a design perspective. The zoom level in my application is used in at least 8 different unrelated subsystems. It's also controlled (changed) by 4 different GUI widgets.
Having the zoom be calculated based on the value of a GUI slider (oh, and I was wrong, I was actually thinking of a combobox/list now, but close enough...sorry) really points the arrow in the wrong direction, in my opinion. The current zoom is the leader of zooming! The actual current zoom level is the piece of data that "feeds" any part of the rest of the system...including the GUI widgets that set (or attempt to set in some cases) its value, the GUI panels that actually display the audio data at the appropriate resolution, to the scaling functions that allow time markers to be created based on mouse clicks. The other pieces of related data (current selection in the combobox/list, slider pixel value, etc. etc.) are all dependent.
I think this is the spirit of what I was getting at: when the data is decoupled from the functions that act upon it, it's much easier to realize a true model-view-controller architecture. If you decide to replace the slider in your example, the zoom code has to be rewritten to be calculated based on whatever widget you decided to change it to. If your functions are separate from the data, all you change is the GUI widget function...all the other pieces stay intact, and still work as originally designed.
Of course, that's the key...now your application is (more than ever) tied to the proper design of your data model. If you didn't design it properly to begin with, or your original cut wasn't resilient enough to cope with change, or your changes are overwhelming and incompatible with your original design...then you've got to change a bunch of things. But that's true for every programming style.
Now it's entirely possible that what you described could be refactored into a much more loosely coupled version, I just haven't thought about it enough and I'm not familiar enough with Cells to know how to do that.
I am not saying I do not find constraint programming interesting or that it would not be fun to simply drop a new rule in the basket as a way of modifying a program. On the other hand, I have heard nothing but nightmares about what it is like to program with multi-way and partial constraints, so I have not been tempted to add anything like that to Cells (so far <g>).
What I've (we've, I guess) found with the system I'm using now is that having tools that can display to you your application topology (not necessarily in a nice beautiful GUI app) and also categorize/classify the interactions between the data and functions that act upon it is absolutely essential. I would imagine that any application of sufficient complexity would benefit from this of course, but since ours is imperative (to a certain degree) and forms a very complex publish subscribe network, it's mandatory. There are interactions that are impossible to reason about without program introspection. I'm not sure if this is a really bad thing, considering that most applications written in the world (without the benefit of a framework like Cells or ours) have tons of undiscovered bugs that are thousands of times harder to find.
I'm going to keep thinking about declarative event handling vs. imperative event handling.
Thanks again Kenny...