I think the whole question is confused by not recognizing that the set of notions (initargs, :default-initargs, :initform) address a different concern than does :formula. Those three are about providing an initial value,...
I see "The :initform slot option is used to provide a default initial value form to be used in the initialization of the slot cid:part1.03000704.07080902@nyc.rr.com."
The slot is indeed being initialized by the inital value produced by a c-input or c-formula form.
Note by the way, that I can start off with:
(make-instance 'box :width (c? (big-long-calculation)))
...and then decide, to hell with it, I can just go with a fixed value. then I just edit to produce:
(make-instance 'box :width 42)
You do not know me, but little things like the fiercer editing required to switch initializations under your scheme are how I decide design issues.
:formula (or any declaration that "this slot is a cell-slot") is about providing reader and writer functions.
I do not understand the above. DEFMODEL still uses :reader, :write, and :accessor for that.
Once you assert that access to the slot's value is provided through a cell's accessor, you have effectively disconnected from the documented meaning of initargs, :default-initargs and :initform.
Hunh? Of course a slot's value is provided by its accessors. Do you mean that I have broken slot-value? Well, no, slot-value still works, but I have made it into a backdoor, so yeah.
You can, as far as I am concerned, disallow or ignore the use of any of these on a cells slot. Perhaps you would be better off using a cells-specific constructor rather than make-instance, since cells doesn't use the usual semantics of the initargs.
That would be a reasonable way to go if confusion reins. Note that this is open source, and it seems to me you could roll your own DEFWHATEVER that thiny wrapped DEFMODEL and substituted a different syntax to get things defined. And you would need a new make-instance and .... hmmm, it could get complicated. :)
I should dig up some earlier versions of Cells. Back in the day, Cell slots were not even slots. A class had one slot for an assoc of names and cells (or literals).
-- But, hey, if you are going to say "its sooo... easy"
What I liked as Cells evolved over time was not so much the ease and naturalness (to me, anyway) of the syntax as that the syntax was just raw CLOS. Sleight of hand took place behind the scenes, but if you understand CLOS, you know the syntax of DEFMODEL (tho we disagree here). I know how to subclass and override (and I also get all the power of CLOS in doing so).
I think the big mistake of something like CLIM is introducing a new DEFTHIS syntax with all new rules to invent and learn.
I do understand your point that confusion arises when familiar syntax is used for something unrelated, btw. I just do not see the Cells usage as unrelated, and the contortions I anticipate of separating initilaization to a Cell from initialization to 42 tell me they are related.
What is unusual is that the initializing value is functional, if you will. C++ /I think/ has computed members. There was wholly different syntax, but then there was no way to vary the computation at instantiation time, nor a way to instantiate with a literal instead. I think. Last time I looked I could not even find the computed slot syntax. :)
sure stick with it. I don't care. I'm trying to help, not trying to be critical.
Also, what do we do about:
(make-instance 'republican :indictments (c-formula ()
(years-in-office self)))
That would override an initform or :default-initarg. How are cells supplied at make-instance time in your scheme?
(mk-republican 'indictments (c-formula () (months-in-office self)))
indictments names a slot, it might not be an initarg.
I think one of the Great Strengths of Cells is that it is raw CLOS (make-instance, initargs, initforms, default-initargs, etc etc). I believe you are on the verge of inventing a new object model, but doing so is the only thing Garnet fans regret about Garnet.
There are a lot of examples in the test suite with some pretty simple relationships. Am I the only one who prefers examples to turgid, abstract documentation trying to sound like a PhD thesis by using big words and never saying what they really mean?
Well, I hope I am not being turgid or using big words. After seeing a couple of examples, I like definitions.
What I find is that good technical writing (well, good writing) is quite rare. So unless the doc is merely defining the legal syntax, once the writer goes for an abstract definition, only someone who already understands the subject can understand the writing.
So far I have this:
A C-INPUT CELL is a cell whose value may be set through explicit procedural code, using setf on the slot. Setf-ing the cell typically causes the values of other cells to be recomputed.
This is a good example of what I just said. Things are fine in the first sentence, where you define c-input according to legal operations on them. Well, there is a little confusion because the reader (or one like me) starts wondering when one would /not/ be able to SETF a slot. I think I always start with ruled Cells and /then/ explain c-inputs as the bottom turtles, if you will, in the overall application dataflow model. Unfortunately, this also gets us smack into an optimization issue: using a raw literal value instead of c-input permits a very nice optimization. I always gloss over that with a bit of "don't ask, it's faster". Anyway, in the next sentence things get tougher....
You tried for a little precision with "typically causes the values of other cells to be recomputed". I know what you are saying and even I find that alarming. I do not like the fuzziness of "typically". Right away I want to know when and when not. And merely saying "other cells" leaves me dumbfounded: Hunh? What other cells?
Hmmm, maybe this is why I do not like reading doc, or why good doc is so hard to write. I do not like mysteries in technical material, but that is what i usually find. getting back to this sentence, again, this is why I try to start with ruled cells. I can say there something along the lines "The slot value will be recomputed when and only when some other slot (a) mediated itself by a Cell (b) accessed during the prior computation (c) changes." Then when I get to c-input I can say: "Changing the value (via SETF) causes any ruled Cells dependent on the c-input Cell (meaning the c-inpuit was used in the most recent computation of the c-ruled) to be recomputed."
Ouch, we are defining Cells by behavior and have not mentioned def-c-output. Maybe we go the other way:
Start with "(defclass box () ((width :cell t...)))".
The first thing that supports is (def-c-output width ((self box) new old old-valid-p) (format t "~&width ~a" new))
But that only gets called once for (make-instance 'box :width 42) because (setf width) is illegal where a cell has bound to it a normal lisp object. To use SETF...
(make-instance 'box :width (c-in 42))
Now you can call (setf width) on this instance. Why is c-in necessary? we get a nice optimization by forcing the user to declare when a slot is changeable.
And now we can setf a series of values into width and see a series of format outputs.
Finally, (make-instance 'box :width (c-in 42) :height (c? (golden-rule (width self))))
etc etc from here on. The only thing is that I am resisting the temptation to say too much about c-input (that it triggers propagation to dependent ruled cells), with the downside that the reader is wondering what the hell all the syntax is about until we get to ruled cells. But if we keep it short and sweet, they are only in suspense for a paragraph or two.
A C-FORMULA CELL is a cell whose value is obtained through evaluation of a formula.
Note that the usual semantics of :initform do not apply when :initform is given by c-formula. Instead of just setting the value at initialization, the c-formula (an arbitrary lisp form) specifies the dynamic relationship between the slot's value and other aspects of the program state.
I don't have a definition of "cell" ...
One thing to be wary of is that I use cells two ways. First, they are the structures produced by c-input or c? which mediate a slot. Second, I use "cell" as shorthand for a slot. So I might say:
"the parent slot of a Child is not a cell because Childs cannot change parents, and Cells are all about change."
That is using Cell as shorthand for "slot managed by Cells internals to which a Cell can sensibly be bound". Or I can say:
"I suspect Cells-Gtk could use fewer c-input cells and more c-formula cells."
There I am talking about what gets bound to a slot that can sensibly have a Cell bound to it.
but I think it is might be:
"A CELL is a slot in a CLOS object whose value is managed by readers and writers that are part of a cells constraint network."
It would be useful to have definition of the 'fm' methods.
Utilities useful for dealing with the Family class. Call me old-school, but I like prefixing, even where I might have a Family package with an FM nickname and use fm:find-one.
As far as I can tell, (fm-find-one top name) just does this:
(depth-first-search top #'(lambda (x) (eql (md-name x) name)) #'kids)))
I would like to see depht-first in the documentation, not the name. Anyway, why are you guessing at what fm-find-one does? Look at the signature:
(fm-find-one family md-name &key must-find global-search skip-tree)
And I just added a doc string:
"Search depth-first from starting point family for a model instance with the given md-name and passing test, skipping skip-tree and searching up the family tree for global-search. Error if not found and must-find."
So how about
fm-other -
See the source:
(defmacro fm-other (md-name &key (starting 'self) skip-tree (test '#'true-that)) `(fm-find-one ,starting ,(if (consp md-name) `(list ',(car md-name) ,(cadr md-name)) `',md-name) :must-find t :skip-tree ,skip-tree :global-search t :test ,test))
fm-other? -
fm-other, but no error if not found
fm-traverse -
see the name. :)
fm-other-v -
fm! - fm^ -
See the source. I forget. :) They are all pretty rare in my code. fm^ starts by searching up from self and excludes self (as the skip-tree). I just looked at fm! This insists on finding the other thing in the self tree (no global search). The mnemonic is "dammit! I know this exists and that it is a descendant of me". None of this wishy-washy "Golly, I know it is out there somewhere because someone else has one" of fm-other or even worse, the "i wonder if anyone made one of these" of fm-other?
I see fm-other-v is wrong, it should be fm-other?-v. It is an fm-other? that evaluates the md-name arg.
It's OK with me if this isn't discussed further.
No such luck. <g> You are asking good questions and I even agree to some extent with your take on my extending the syntax of :initform and :initarg, and I really am impressed by your success so far providing documentation for Cells-Gtk, so I am happy to respond.