Some comments interspersed for those not comfortable with virtual fields. The primary context here is UD, but I note some differences between UV & UD. Then an example. cds
---------------------------- From: Anthony W. Youngman >Certainly I would recommend never pointing a virtual field By the way, the term "virtual" comes from UD, not UV. I like it, because it nicely distinguishes between stored & derived (real & virtual, respectively). UV sticks with the old Prime "Information"-descriptor wording. UD allowed dictionary items as either "I"- & "V"-types, synonymously; UV, "I"- only. > at a virtual field in a different file, You can't with UV. I wish you could. I did not know UD allowed it. I don't see that as _inherently_ bad, just abusABLE. See more comments below. > but wouldn't think twice at pointing virtual fields at each other > in the same file Right. I encourage it. It's called REUSEABLE CODE. The only downside is a lack of a native tool for managing dictionary snippets. What I mean is, I'd like to look at a UniQuery/RetrieVe sentence, see all the dictionary items it references, including related, nested virtual fields in a way that is easy to read and maintain. The best tool I have seen for doing that is called SoftWhere, by Joe Toledo. I think Ray Jones has something, too. Others? > (provided they don't use @n syntax!!!) UV imposes this restriction. If you attempt to reference an I-descriptor where the nested I-descriptor does not have multiple calculations, separated by semi-colons, it won't compile. (This is a weakness, in my opinion. Probably deep in the I-descriptor compiler and not easily changed.) ---------------------------- Example demonstrating double translate, reusable code, @n-syntax: TOTAL.COST 01: I 02: PRICE * TAX.RATE TAX.RATE 01: I 02: TRANS( STATE.TABLE, TRANS( CUSTOMER, CUST.ID, STATE, 'X' ), TAX.RATE, 'X' ) @n-syntax: --------- If you are going to reference it from TOTAL.COST, this is not allowed: TAX.RATE 01: I Customer's tax rate. 02: TRANS( CUSTOMER, CUST.ID, STATE, 'X' ); TRANS( STATE.TABLE, @1, TAX.RATE, 'X' ) which is a shame, because it is more readable. Concerning efficiency in the above: ---------- I would not hesitate to do the above double TRANS(). TAX.TABLE is likely to be small. It is likely to be loaded into memory by a modern OS and remain there for the duration, probably even permanently cached on a busy system. If your data is sorted by customer, so that you are going after the same record repeatedly through your RetrieVe/UniQuery statement before advancing to the next, the OS will likely keep that same one cached in memory for the duration, too. Furthermore, on UV (UD, too??) TRANS() has some efficiency built in, too. If you ask TRANS() for a field from the same record as last time, it has it cached. So if your report lists CUST.NAME CUST.ADDR, CUST.PHONE, etc., for the same CUST.ID, TRANS() gets the CUSTOMER record only once. (By the way, I find on UV that I simply cannot devote too much memory to caching files. The more memory, the better. I don't know how UD compares, but for some reason, UV demands this more than our Oracle, Informix, and SQL DBs, to achieve acceptable performance. Conversely, UV leaves a smaller per-process private memory footprint.) Reusability: ------------ It is nice to define TAX.RATE once in this dictionary. Putting TAX.RATE in it's own V- or I- descriptor and referencing it from TOTAL.COST, other virtual fields, or explicitly is nice because maybe today it is a simple lookup in STATE.TABLE, but next year it might be a subroutine call to account for Canadian methods, or in 2009, after President Steve Forbes replaces US income tax with a national sales tax... Even more Reusable: ------------------ The way it is now (in UV), every dictionary (or program) that knows a CUST.ID and needs a tax rate needs to do the double lookup: cust->state->taxrate. What would be nicest is if TAX.RATE could be defined in CUSTOMER dictionary as a virtual field (perhaps a subroutine call for the multi-country case) so that rather than needing to do the double translate, you reference TRANS( CUSTOMER, CUST.ID, TAX.RATE, 'X' ) and you get back whatever data retrieval or calculation is defined ONCE in DICT CUSTOMER. In UV you cannot do this. Can you in UD? I suppose this is a sub-topic of the larger issue (virtue or tragic flaw; see flames in past threads) of the loose [non-]coupling of dictionary & data access methods. cds ------- u2-users mailing list u2-users@listserver.u2ug.org To unsubscribe please visit http://listserver.u2ug.org/