Josip Gracin wrote:
Thomas F. Burdick wrote:
you need a suite of tree- or net-searching utilities to really enable the declarative style that makes Cells such a win.
This is what I don't actually understand. I'm writing a simple aircraft simulator and I have a bunch of defmodel definitions for various systems, a bunch of input and output cells and I expect output cells to provide new values whenever their dependencies are changed. Currently, this all works beautifully for me and I haven't used any explicit network modeling/searching. I'm wondering if I am missing something.
As an example, I have something like the following:
=================================================================
(defmodel flight-parameters () ((speed :initarg :speed :cell t :initform (c-in 0) :accessor aircraft-speed) (altitude :initarg :altitude :cell t :initform (c-in 0) :accessor aircraft-altitude) (heading :initarg :heading :cell t :initform (c-in 0) :accessor aircraft-heading)))
=================================================================
(defclass aircraft () (flight-parameters :initarg :flight-parameters :accessor aircraft-flight-parameters) (lights :initarg :lights :accessor aircraft-lights :documentation "Light system.") (light-switches :initarg :light-switches :accessor aircraft-light-switches) (flaps :initarg :flaps :accessor aircraft-flaps) (gear :initarg :gear :accessor aircraft-gear)))
=================================================================
(defmodel b777-flaps (flaps) ((lever-position :cell t :initarg :lever-position :accessor flaps-lever-position) (real-position :cell t :initarg :real-position :accessor flaps-real-position) (transit-start-time :cell nil :initarg :transit-start-time :accessor flaps-transit-start-time :initform 0.0) (transit-start-position :cell nil :initarg :transit-start-position :accessor flaps-transit-start-position :initform 0) (:default-initargs :lever-position (c-in 0) :real-position (c? (flaps-real-position-fn self))))
What your example does not show is how one model instance finds another instance. In my Family-based code I have functions that search the family DAG by name (where the .md-name slot is "the name") or by type. The advantage is that I do not have to know exactly where in the tree something is, it just has to be somewhere. A radio button is on if the nearest radio-group-manager instance searching up the model has the radio button's value as its value. The coach widget is visible if the check-box named :show-coach has a value of t. etc etc.
Your model will have cockpit controls that make rudders and other surfaces move, and indicators that show their position. Now you can write code for the indicator for landing gear #5 that says (position (aref (landing-gears *plane*) 4)) and you will be fine, but some of your "finding" is being done with a special variable that needs maintaining and some of it is being done with a hard-coded API (you are relying on the landing-gears function knowing where to find them on the plane -- does the plane own them, or are they nested components of an intervening "frame" subcomponent?) In the latter case if you redesign the OO model for the plane, all the functions hard-coded to locate other instances have to be revisited to see if they still hold. So that code is a little brittle, more so the more you are into refactoring.
Especially in a GUI, I might decide to add a second button alongside a first button. So now I put a row widget in the view hierarchy where the first button was and it gets two kids, the first and new second button. Any interwidget dependencies are fine, because searching by name or type they will still find each other (within the capabilities of the Family navigational tools).
hth, Ken