Sunday, 18 July 2010

Disagreeing with the Past

I've been trawling through past articles and snippets that I've written, and came across this letter to the new editor of Dialogue in which I disagreed with an article in the previous issue.

I don't remember ever sending this! But since I don't disagree with what I wrote then (this was April 2002), and since I still see DOS-like code permeating DfW and Ff apps, I'll print it now.

You'll have to imagine the article I was replying to, unless you have a copy of that issue.

Dear Editor,

I beg to differ with some points made in the article on page 39 of the Winter 2001 Dialogue discussing DfW procedure rules.

“Where possible, fields that sort or group should be at the top of the procedure.”

This is misleading.

The position of grouping in a DQL determines which form/record object set a field belongs. It is not merely a matter of positioning them “at the top”, but understanding how where they are positioned affects the QBM and body created.

For example:

for Invoice ;
list records
CustomerID in groups ;
CustomerName ;
Amount .

creates two containers – one for the grouped items, and one for the items that belong to that group. A previously – and maybe even currently – undocumented ‘feature’ is that all the fields above the grouped field belong to the group container.

Here the customer name will repeat for every item in that group, which I presume is not what the user wants.

The proper DQL is:

for Invoice ;
list records
CustomerName ;
CustomerID in groups ;
Amount .

This will position CustomerName in the container it belongs – the grouped items – and not in the individual records for that group.

In DOS, people were used to writing the DQL and then re-arranging the fields in the format. In DfW, you must write the DQL to position the fields in their proper container in the body.

For the same reason, listing in order should be done in the appropriate container. Thus:

for Invoice ;
list records
CustomerName ;
InvoiceDate in order ;
CustomerID in groups ;
Amount .

Putting InvoiceDate above CustomerID will result in that field appearing in the grouped container, and only showing the value of the first record in the group – again, not what the user wants.

“Ad-hoc relationships based on virtuals…”

One key problem with virtual fields is that many people don’t understand how to use them properly. In addition, whereas the DOS environment meant that even absurd coding using virtuals was usually ignored, the Windows environment brings with it new memory issues that allow for multi-tasking and the like, and cannot be ignored.

As I pointed out a few Dialogues ago, I found a vertical 4.53 application that I migrated for testing purposes to DfW. I found that it migrated fine, except for one problem – a virtual field derived as “lookup ThisRel Value”, where the virtual itself was the match in the relationship! DOS forgave this; DfW (rightly) objected.

Whilst I would say that one source of GPFs is poor use of virtual fields, I would also say that, used properly, virtuals belong in the DataEase application (see, for example, Chris Gadsby’s excellent article on project methodology in the same issue, p18, col 1, “Entity Level Data Dictionary”, in which he singles out as part of the process the identification of virtual attributes).

Thus my concern is that people are put off using virtuals “because Sapphire said so”. You were correct that they “may cause recursive calculations” … but then again, they may not.

I also think that the ‘recursive problem’ is not limited to ad-hocs, but applies to all relationships.

“Reference to System forms are invalid in DfW…”

Since when? That should be ‘system tables’, of course, but I know of no reason not to use them, as long as DfW has a corresponding table. After all, the DQL scheduler is just a pseudonym for “for system configuration with computer name = blank…”.

Of course, you have to check “show system tables” in the application preferences dialog. And maybe some of the things people do with system tables are dubious. But the above statement is in and of itself incorrect.

“The output command .. in many cases … can be dropped.”

Whilst it is correct to point out its redundancy, I’d say that in every case it can be dropped, though please give an example of where it can be kept if I’m wrong. I’ve never used it in a DfW application, since we can use nested fors and multiple list records instead.

I’m slightly dubious about the line “if a … procedure has multiple non-nested for loops, break it up into separate procedures”. Such constructions are possible, as long as one understands how the QBM/multi-view is affected. But I agree that ‘rambling’ DQLs that don’t respect the QBM/multi-view are likely to be problematic, and am minded that you group these under “other general rules”, especially since such considerations were not applicable to DOS, and therefore even the best programmer could code stuff that won’t work in DfW. Your recommendation in the next paragraph to “keep procedures to a single outer for loop” is good advice.

The article also continues to refer to ‘forms’. The longer the DataEase developer/user confuses forms with tables, the longer it will take to appreciate the true power of separating form and table design.

I agree with all the other suggestions and comments made in the article.

Sorry to sound so harsh, but I’ve tried in these pages and on the various forums to develop a true understanding for the readers of how DfW works, and to overcome some of the many mis-assumptions about the product.

Your turn to disagree...