4gl improvement thoughts
Posted in 1993
I was chatting with tech support a while back, and mentioned I had a
"wish list" for enhancements to 4gl to turn it into a significantly more
enjoyable language to program in... I was asked to mail it, but I thought
since there are so many @informix.com's on here I'd also post it.
[Oh, did I mention, this would probably give you a big edge against
your competition? But as it is, 4gl is pretty sad. I'd call it a 3gl+.]
I know some of these can be worked around easily enough, but they're
still nuisances. (Compared to the cost of 4gl, I'm still incredulous
how weak it is.) I know Jonathan Leffler had a composite list of ideas,
and many of these are probably on that, but I couldn't find my copy of it
to cross-reference. Some are perhaps "Not a Good Thing", but I hope each
at least contains the kernel of a useful idea.
1. Manifest constants. I find it incomprehensible that I have to hardwire
constants in a language that promises to be easier to write/maintain/etc.!
Not to mention one that's based on C. C'mon, this is a whole "generation"
better than C?!?
Right now I have it jury-rigged to allow
%define MAXFOOS 100
via cpp. ('%' being a selectable char, but one I happen not to be using
for anything else. '#' has the obvious problem of being for comments;
in fact these can upset cpp, so they're stripped out too, except in "using".)
Note this means you can take advantage of token pasting and stringizing in
cpp too.
This also allows real macros -- great for making templates for functions
since parameter passing is so limited.
Also allows %ifdef, etc. All the ANSI cpp features should be present.
2. An elseif. A minor nuisance, but probably easy to add.
3. Let x.* = corresponding y.*. I.e., copy those elements with the same
names from y.* to x.*.
4. The 8 character limit to names. Really a nuisance since we seem to
be expected to use code generators and repetitive code. Especially for
function names this can be a nuisance.
5. Call by reference. A C++ish reference syntax would be fine,
function foo(r)
define r integer reference
with no syntax change for the call.
6. Passing arrays, both by value and reference.
7. Function calls anywhere, esp. in SQL:
(1) select ... where t.foo = bar(stuff),
(2) let x = bar(blech(stuff))
#1 would obviously be a significant enhancement beyond the sql standard, but
not impossible to implement (shipping the data back from the sqlexec
to the 4gl code may not be pretty or efficient, but it would sure be nice).
#2 seems to work in some cases, not in others. Needs to be consistent.
8. If exists: IF TABLE doc EXISTS
IF COLUMN doc.field EXISTS
Yes, it can be kludged around but this would be cleaner.
9. Rec.* in any context: if rec.* = orec.*
10. Fix for: if s clipped = ""
I think having to "work around" via if length(s) = 0
is silly. It would be nice if this problem (and others)
were visibly documented. If one wants to get fussy about "" being null,
I guess I'd want to open up the debate to whether "" is the optimal
representation for null; I think not, truth be told.
11. Control-Z in RDS doesn't restore the termio modes right. I suppose this
could just be a bug in my version consider this a report of it.
(After 'fg' the terminal is not reset to cbreak mode.)
This is with the AT&T starserver version; running under tcsh in case
that's the catalyst (since tcsh plays with modes).
12. Dynamically sized and arbitrary length arrays:
define foo array[n] ...
and
define foo array[*] ...
(the latter allowing "any" number of elements, i.e., it grows like a csh/perl
array). Of course, input/display array MUST work with these.
13. Associative arrays would be too cool. (For those unfamiliar with awk/perl,
this means:
let arr["string-thing"] = whatever
and a loop like
foreach i in arr
fiddle(arr[i])
.)
This foreach loop would be nice for numerically indexed arrays too, even if
assoc. arrays are rejected.
Even better:
foreach index i in arr
fiddle(arr[i])
plus
foreach value x in arr
fiddle(x) x is arr[current]
14. Input array allowing one to pick N of M entries.
14a. Input array not requiring a modifiable field to work (for pick lists) --
or maybe what's really needed is a new statement like an input array, but
something like
CHOOSE {1/n/ANY} FROM arrayname
with 1 the default. Each item is presented as is, readonly, in window,
scrollable, etc. like input array, but with the ability to either highlight
the entry when picked [(and unpick) via "OPTIONS CHOOSEKEY key" and
"OPTIONS UNCHOOSEKEY key" (default return)], or show a checkbox in front
of the item. Should definitely work for multi-field values when array is
an array of records. Should allow
... returning thing.* -- for one thing
... returning things.* -- an array of those chosen
or perhaps a parallel array of true/false which were chosen:
for i = 1 to Nthings
if CHOSEN[i] then
fiddle(things[i].*)
15. Insert/delete row statements for arrays (with auto adjustment of
indices).
16. Unions for columns, enumerated types:
create enum idtypes (byssn, byempno, bylogin, byphone)
create table foo (
idtype enum idtypes,
union (
ssn char(9),
empno integer,
login char(8),
phone record like phoneinfo.*
) id,
...
)
...
case f.idtype
when byssn
if f.id.ssn is NULL then
.......
In my current development, there is a field that can hold one of a couple
dozen types of data, and coding everything a couple dozen times is a
real pain. (It would consume way too much space to let each row have
one column for each.)
17. Better pattern maching -- e.g., Henry Spencer's regexp package. (I've
loaded this in via the 4gl/C interface, but it's still not usable in
select/matches, construct, etc.)
18. Better validation -- allow validation via a boolean valued function call.
19. Local variables to blocks
20. Allow "define" on any line (a la C++).
21. Forms: Line draw needs to have hooks for the various 'T' characters.
22. Froms: Double and single line draw hooks, at same time.
23. Forms: Allow changing types of delimeters. (I.e., multiple sets.)
Suppose I want to have one field with no delim, but others with [].
24. In forms, allow adjacent fields and fields adjacent to text:
Item [n]:
leaves an annoying space between the number and the ":". Also
Part#: [dept(4)+item(4)]
(for a field width of 8).
25. Forms: Allow ______ marked fields (i.e., display as
foo: __________
Or other user specifiable character.
26. Color support for terminfo's that do color (i.e., not just termcap).
27. Attributes for menus, messages.
28. Allow setting the background color.
29. Optional true/false binding for null values --
if x = y WITH NULLS EQUIVALENT then
plus a default mode,
set null_logic two_valued
vs.
set null_logic three_valued [default]
and as a bonus,@@N