QB/FB arrays are the worst designed feature in any programming
language I know of (except for *possibly* some of the stuff in MUMPS
http://thedailywtf.com/Articles/A_Case_of_the_MUMPS.aspx)
(A quick rant:
-not 1st class: you can't return them or even place them in types!
-uninitialised dynamic arrays are indistinguishable and will crash
your program. You must initialise them.
-to figure out whether an array is static or dynamic you have to check
the dialect, the OPTION statements in effect, and whether the index in
the DIM statement is a variable or a constant
-unlike the rest of the language, arrays aren't properly statically
typed: the compiler will let you REDIM a static array and crash your
program
-zero-length arrays not supported
-almost zero support for arrays in the standard library: just REDIM,
LBOUND, UBOUND, ERASE. You can't even copy an array, or get a pointer
to the array descriptor.
)
A couple days ago I had finally had enough, and started on a library
of array utility functions written in C, effectively extending libfb
(addressing just the last 2 complaints above). The idea is they act on
1D arrays starting at -1, with the -1 element ignored so we can have
zero-length arrays. Here are a few prototypes (you use a macro to
declare overloaded versions for each type T you want to support):

  declare sub array_copy overload (array() as T, source() as T)
  'Append an element or an array
  declare sub array_append overload (array() as T, value as T)
  declare sub array_append overload (array() as T, appendlist() as T)
  'Removes index n from array
  declare sub array_delete overload (array() as T, byval n as integer)
  'Insert a value/array at an index. Negative indices count from end
(-1 appends)
  declare sub array_insert overload (array() as T, byval insertbefore
as integer, value as T)
  declare sub array_insert overload (array() as T, byval insertbefore
as integer, insertlist() as T)
  declare sub array_sort overload (array() as T)

A couple nights into implementing them (expected to be done by now,
but the libfb array code is horribly over-complex, eg. there are about
8 different implementations of REDIM) I suddenly realised: if FB
arrays are so horrible, why am I using them at all? It would be FAR
easier to create a new array structure and write an extensive library
for it in C. The code would be much simple, faster, there'd be no
worry about keeping up with changes to libfb, and I can fix more of
the problems with FB arrays. The disadvantages would be having to
manually allocate and free them, and no bounds checking when compiled
with -exx. However when we finally switch to -lang fb we'll get those
back.

I would implement these arrays like this: array objects would just be
pointers of the desired type, which can be indexed like a normal
pointer. The array descriptor (containing length and other stuff)
would be stored before the 0th element. These pointers can of course
be embedded in UDTs or returned from functions. Because code should be
self documenting, to avoid confusion with normal pointers I'd do this:
#define array ptr
Example code:

FUNCTION generate_test_array() as string array
  DIM arr as string array
  array_new arr    ' allocate zero-length array
  array_append arr, "test"
  array_append arr, array_of("foo", "bar")   ' I think I'll manage this
  array_sort arr
  RETURN arr
END FUNCTION

DIM arr as string array
arr = generate_test_array  ' Can only do this as arr is a NULL pointer
array_set arr, generate_test_array  ' Safe way to assign an array
print arr[length(arr) - 1]
array_free arr

So the question to the other developers is: would you rather have a
library for FB arrays, or use these new arrays? I am definitely in
favour of the new arrays, and would start using them and, where
beneficial, converting code I'm working on to use them as soon as
possible (tomorrow?).
_______________________________________________
Ohrrpgce mailing list
[email protected]
http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org

Reply via email to