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

Reply via email to