On 27 November 2010 00:16, Seth Hetu <[email protected]> wrote:
> "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

At first it looks like the worst language ever, but then I realised
that this was actually probably the second most flexible and powerful
(after Lisp of course) programming language existing back in 1970. The
list of features is extremely impressive for such an early language.

Quote from the FAQ:

f p=2,3:2 s q=1 x "f f=3:2 q:f*f>p!'q  s q=p#f" w:q p,?$x\8+1*8
     [part of Keith Lynch's .signature; it prints a table of primes,
      including code to format it neatly into columns--DPBS]


> 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
>
_______________________________________________
Ohrrpgce mailing list
[email protected]
http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org

Reply via email to