"GLOBAL ARRAYS... start with a caret symbol. Stored on disk, available to all processes"
"You see, because MUMPS has a rather small routine limit, developers had to spread code across several routines... and “chain” them together with a GOTO at the end." This is now my favorite programming language ever. -->Seth On Fri, Nov 26, 2010 at 6:59 PM, Mike Caron <[email protected]> wrote: > On 11/26/2010 5:34, Ralph Versteegen wrote: >> >> 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?). > > I'm curious about one thing. Would these new arrays be dynamic or statically > sized? I assume the former. In which case, you do you handle the > realloc()/Reallocate() semantics? > > Specifically, when you use realloc(), you have to use the return value as > the new pointer (if it's not null), since the memory block may have moved to > accommodate the new size. > > However, the syntax you're proposing does not allow for the re-assignment of > the variable containing the array. (Unless you intend for some preprocessor > trickery, in which case foo on you.) > > The best way to replace FB's arrays would be to create an array object which > overloads the [] operator, and keeps the memory buffer internal. Ideally, it > supports templates for maximum efficiency. > > Class Array<T> > length as uinteger > data as T ptr > Public Constructor Array(size as uinteger) > length = size > data = new T[size] > End Constructor > > Public Operator[](index as uinteger) as T ref > if index < 0 or index >= length throw new ArgumentException() > > return &data[index] > End Operator > > public sub Resize(newsize as uinteger) > ... > end sub > End Class > > However, since I don't think this possible in FB (and, especially not in > -lang deprecated), you would have to settle for a C-style api: > > TYPE IntArrayUDT > length as uinteger > data as integer ptr > End Type > > TYPE IntArray as IntArrayUDT ptr > > Function NewIntArray(size as uinteger) as IntArray > Sub DeleteArray(a as IntArray) > Function ResizeArray(a as IntArray, newsize as IntArray) as integer 'boolean > Function GetArray(a as IntArray, index as uinteger) as integer > Sub SetArray(a as IntArray, index as uinteger, value as integer) > 'etc. > > Also, I would be very tempted to use some evil preprocessor trickery to > simulate templates, since this is very silly. > > Or, the final option would just to use regular pointers as arrays. It's > worked for almost 40 years so far :D > _______________________________________________ > Ohrrpgce mailing list > [email protected] > http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org > _______________________________________________ Ohrrpgce mailing list [email protected] http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org
