On 27 November 2010 04:01, Mike Caron <[email protected]> wrote: > On 11/26/2010 7:49, Ralph Versteegen wrote: >> >> On 26 November 2010 23:59, 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? >> >> I forgot to mention? Yeah, always dynamic. >> >>> 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.) >> >> BYREF BYREF BYREF > > Well, *expletive*. I guess I've been using other languages too long.
And I've been using FB too long :( >> Don't worry, there's preprocessor trickery involved. However there's >> less than required for extending FB arrays. Also, I am aware that my >> attempts at inheritance, hash tables, and lists using macros turned >> into a disgusting mess; I promise I won't do that again. In fact I am >> thinking about porting lumpfile.bas to C++ so that I can get rid of >> the macros and custom polymorphic class system. > > Fun fact! C++ 1.0 was nothing more than a glorified set of macros! >> >>> 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. >> >> Yes I agree, if we had classes I would be using them. It won't be much >> work to switch to classes when we get the chance to. However, it will >> never be possible to switch the extended FB arrays library to classes, >> which is another reason to use our own array type. >> >> Also, I'll note I'm building in support for types with constructors, >> copy constructors, compare operators, etc now, and will provide a >> -lang fb test suite. >> >>> 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() >> >> Umm is this VB code? > > I am 99.999% certain that no compiler would accept this snippet as valid. > That's the MikeBASIC(TM) guarantee! Thank goodness. Exceptions in FB are best left to your imagination. >>> 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: >> >> I thought that you could overload operator() or operator[], but I >> don't see it right now. I know very little about -lang fb stuff. >> >>> 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 >> >> GetArray is far too verbose for me, which is why I suggested direct >> access to a pointer. I'd rather go with extended FB arrays than have >> to type that. > > Yeah, me too. Just being complete. OK, so you'd actually suggest everyone access via the data pointer instead, then. >>> 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 >> >> The whole point is that FB provides no useful functions acting on >> arrays whatsoever, so I want to write a library. Otherwise I will >> either go insane, or quit OHRRPGCE work and blissfully write Python >> code for the rest of my life. > > The only real counter argument is that it's already been written and named > the standard c library. I forgot to mention that advantage of C arrays over FB arrays. But it would be far more accurate to say that I'm replicating C++ STL vectors plus some of <algorithm>. Because that's basically the plan (aside from the code bloat due to separate versions for each type used). _______________________________________________ Ohrrpgce mailing list [email protected] http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org
