Hi all, it seems to me that '+Need' causes expectations it cannot fulfill. I can sometimes see E/R models with '+Need' in almost each relation, but in reality it is not as useful as it might appear. Let me try to explain the rationale behind it.
The philosophy of PicoLisp is to give a maximum of control and flexibility to the programmer. The entity/relation framework in "lib/db.l" is rather low-level: It automatically maintains all necessary data structures, but it does not stop the programmer from doing something "illegal". He can directly manipulate all those structures with list- and symbol-functions, at any time. So what is a '+Need' class supposed to do? It should enforce the presence of certain properties in a database symbol. But *when* should it do that? When a new symbol is created? This is not possible, because a new symbol does not have any properties at all. The properties might be 'put' one after another, so there is never the right time. And *how* should it do that? Issue a hard error (e.g. with 'quit' or 'throw')? This would not be wise, because it does not allow the graceful handling of such situations in higher layers. Therefore, the '+Need' class is strictly "cooperative". It supplies the 'mis>' method, which can be called from higher layers as needed. Currently, this is from the 'chk>' method of fields in "lib/form.l", and also from the interactive 'update' function in "lib/sq.l". In a similar way, it could be called by other custom database functions. The 'chk>' message is sent to each field in a form whenever a button is pressed. When any such method invocation returns non-NIL (i.e. an error string), processing of that button press is aborted, and the error message is displayed to the user. The result is that the user cannot input a value into a field for which the field's 'chk>' method signals an error, because the only way to get values from the GUI into the database is via button presses. But even so, this is still too "hard" in certain cases. Imagine an entity class which has '+Need' for several relations. When an empty form for such an object is presented to the user, he will not be able to press any buttons without an error before he has filled in all required fields. This might sound ok at the first sight, but can be an annoyance in practical use. For a typical application, for the very act of filling those fields, a button press is often necessary to present a search dialog or a choice list to the user, making it virtually impossible to fill in the form. In addition, why should we not allow the user to fill only part of the form, save it, continue with some other work and resume later? In essence, my rule for '+Need' is: Use it only for such relations where the *program* guarantees that a value is initialized before that object is presented to the user. Look, for example, at the order class in "app/er.l": (class +Ord +Entity) (rel nr (+Need +Key +Number)) # Order Number (rel dat (+Need +Ref +Date)) # Order date ... There are two '+Need' relations. A new order is always created with both values: The "New" button in the 'choOrd' function calls (see "app/gui.l", line 234): '(newUrl '(+Ord) '(nr genKey 'nr '+Ord) 'dat (date)) That is, the new order is always initialized with a newly generated, unique order order number 'nr', and the order date 'dat' set to "today". When the user later edits such an order, it is not possible for him to delete the date (though he might change it) because the 'mis>' method of '+Need' will complain. Other cases of 'mis>' are much more useful, like in the '+Key' class, disallowing a user to input a conflicting value into an attribute with a unique key. Or other 'chk>' methods, like in '+DateField', which guarantees only legal date formats. The best, most flexible, and most user-friendly way to implement runtime checks is IMHO a dedicated 'check>' method. There is an example for it also in "app/er.l" and "app/ord.l". The 'check>' message is always sent to an object when something has to be done with that object, not while it is being edited. In the "app/" example it is only for printing, but in a real application it will be used also when an order is booked, or otherwise calculated with or operated on. This is the moment when all data *must* be present, and this is also the only moment where circular constraints can be checked. The above explanations refer the the 'form' GUI, but they are valid for any interactive framework. My recommendation is to use '+Need' with great care, or perhaps not at all, and put constraints resulting from the application logic into arbitrarily sophisticated 'check>' methods. Cheers, - Alex -- UNSUBSCRIBE: mailto:[EMAIL PROTECTED]