Re: A Better Way To Write Pick/Browse Lists [1/4]
Posted in 1993
In article <1str6eINN4c7@emory.mathcs.emory.edu> alan@effluvia.den.mmc.com (Alan Popiel) writes: > > I suppose it depends on your benchmark test. I agree that writing > > IF a = b THEN > CALL foo () > END IF > > is not 10 times as easy/productive as > > if ( a == b ) { > foo () > } > > HOWEVER, please tell me what is the C equivalent of > > MAIN > MENU "MAIN MENU" > COMMAND "File" "File submenu" > CALL file_sub () > COMMAND "Edit" "Edit submenu" > CALL edit_sub () > COMMAND "Report" "Report submenu" > CALL report_sub () > COMMAND KEY(X) "eXit" "Exit from program" > EXIT MENU > END MENU > END MAIN > > That's 12 lines of code. While I am not well versed in C, I would guess > that the equivalent functionality would require considerably more than > 120 lines of C code. Not if you know what you're doing, and you have a good function library. What you're doing could be expressed in classical C (i.e. not C++) thusly: (Excuse me if I get the semantics of what you're doing wrong... I'm not well versed in 4GL!) main() { static menu_list mymenu = { { "MAIN MENU", NULL, NULL, NULL }, { "File", 'F', "File submenu", file_sub }, { "Edit", 'E', "Edit submenu", edit_sub }, { "Report", 'R', "Report submenu", report_sub }, { "eXit", 'X', "Exit from program", EXIT }, { NULL, 0, NULL, NULL } }; call_menu(&mymenu); } If you don't like declaring static structs, you can always have a function suite (with commands like new_menu, add_to_menu, etc.). Motif, for example, basically gives you both choices. The only catch to C is that you (or someone) has to write the function library. IMHO that's a Good Thing: A computer _language_ should provide minimal base functionality, and a convenient mechanism for adding features (which is done in C, lisp, Pascal, et al through function/procedure libraries). In my example, the definitions of the type "menu_list" and the function "call_menu()" are part of the library. Viewed in this light, 4GL becomes a bad language (because it's not very extensible) with a good built-in library. Personally, I'd *much* prefer C (or better, C++) with a well-written library. (This is _not_ to say that C isn't full of shortcomings... It is!) This comes back to what is meant by a "powerful" language. Many people think that the "power" of a language is measured by its built-in features. IMHO it's not. More important is extensibility, and the ability to support software engineering abstractions. If all 4GL gives me are windows and menus and some type checking, then I'll save the five grand (or whatever), and buy the source code for window/menu libraries -- such libraries are a dime a dozen. ANSI-C gives pretty decent type checking, and gnu gives me a great debugger. My initial post was triggered by a bit of amusement at the hoops that apparently had to be jumped through to write a 4GL library function to do pick/browse lists (especially the lack of pointers to functions). I was amused because I just finished writing an extremely general function that does exactly the same thing -- and it took me less than a day. Here's its prototype: extern int edit_da ( dynamic_array da, /* dyn. array to edit */ int number_across, /* # in x dimension */ char *datum_fkey_name, /* Name f/F keys */ int (*show_screen)(void *user_data, int num_entries, int *no_wanted), /* Show screen funct. */ void (*show_entry)(void *user_data, int y, int x, int index, /* 0..da_entries()-1 */ void *entry), /* Show entry funct. */ void (*help_funct)(void *user_data), int (*find_funct)(void *user_data, dynamic_array da), int (*insert_funct)(void *user_data, dynamic_array da), int (*delete_funct)(void *user_data, dynamic_array da, int index), /* 0..da_entries()-1 */ int (*edit_funct)(void *user_data, dynamic_array da, int index), void *user_data ); That prototype is a bit intimidating, but it's not so bad... An actual call to it is compact and relatively clear. Because I'm using ANSI-C, all of my parameter types are checked for me (even of the functions passed as pointers). Because I'm using a language that lets me define new types and pass pointers to functions, it's easy to add features to my "language" in this way. I use this same pick/browse list function to edit a shipping rate chart (70 entries/page), a list of addresses (six per page, each 6 lines by 40 characters), and a list clients. The edit_da function provides the next page/last page/find entry/select entry functionality, and I just have to provide small functions to display/etc. each different datatype that I want to edit. The point is that C lets me write a generic function that can reasonably manipulate a list of xxx, where I can just pass the function what xxx means. From the Pick/Browse example, it looks to me like 4GL gets in the way of this kind of thing. Regards, Bill -- Bill Foote bill@pds.com PDS Corp, Los Angeles, CA USA uunet!promdist!bill