Hi,
since this post is a suggestion to improve the BlitzMax language, it is mainly addressed to Mark Sibly, however, everyone should feel free to post comments.
When I lately wrote some code working with arrays I had trouble with the fact that every BlitzMax array dimension has its own variable data type, e.g.
You can see that this subclassing hierarchy can solve some problems and would be therefore nice to have. I can imagine the only issue of this change in the language can be the backwards compatibility; the most programmes written before this change, working with strings and arrays would compile as well with the change, e.g.:
Additional you could do this vice versa with Len: till now Len is a keyword indicating that the Len-operator is used. If the compiler detects a "Strict/SuperStrict 1.26" statement it doesn't treat Len as keyword anymore - Len is then a function sitting in the brl.retro module.
I know it would be a lot of work to implement this in the compiler, but the result of this change would really solve this and maybe some other issues. So you can see what the work is worth - how do you think about that?
since this post is a suggestion to improve the BlitzMax language, it is mainly addressed to Mark Sibly, however, everyone should feel free to post comments.
When I lately wrote some code working with arrays I had trouble with the fact that every BlitzMax array dimension has its own variable data type, e.g.
Local Array [,]is not the same type like
Local Array [,,]The first one contains a two-dimensional array, the second one conatins a three-dimensional array. This is needed for the compiler to decide how many indexes are needed to index this array. However, this is not usefull if you want to write a function which accepts all types of arrays. Therefore I thought about how the language needs to be designed to make this possible. And I came to the result that it's generally not the best that Arrays (and also Strings) are directly extended from type Object. If I showed this graphically I would write:
Object | |--> User defined type | |--> String | |--> 1D Array | |--> 2D Array | |--> 3D Array | ... | '--> *D ArrayI don't like the idea that everything is directly extended from type Object. It would be much better to work with a hierarchy, where all sorts of arrays are extended from a base array class and String and this base array class are extended from a class indicating that they're both containing collections of elements. It would look like this:
Object | |--> User defined type | '--> Collection | |--> String | '--> Array | |--> 1D Array | |--> 2D Array | |--> 3D Array | ... | '--> *D ArraySo String is extended from Collection and Collection is extended from Object; one-dimensional array is extended from Array and Array is extended from Collection and Collection is extended from Object. The big advantage of this is that you now can write functions which accept any type of array, e.g.:
Function SearchArray ( arr:Int Array , find:Int ) 'search an index in an array Local ArrDims:Int [] = arr.Dimensions ( ) Local DimCount:Int = Len ( ArrDims ) 'this way we can get the number of dimensions Local Total:Int = 1 For Local N:Int = 0 Until Len ( ArrDims ) 'Calculates the total number of elements Total :* ArrDims [ N ] Next Local ArrPtr:Int Ptr = arr 'Get a pointer to the fist array element For Local Index:Int = 0 Until Total 'Iterate through all elements If ArrPtr [ Index ] = find Return Index 'If we found the element, return the index EndIf Next Return -1 'Nothing found EndFunctionAnd since String and Array are both extended from Collection, you now also can write code, which works with both, stirngs and arrays. And this could be really usefull to solve another issue: you can now remove these ugly bits of the language, as you said yourself - Len could become a real function, and wouldn't be an operator anymore! It could look like this:
Function Len ( param:Collection ) 'Len accepts a collection as parameter Return param.length EndFunctionA Collection is either a String or an Array, and both, strings and arrays provide a length field, so Collection should provide a length field, too.
You can see that this subclassing hierarchy can solve some problems and would be therefore nice to have. I can imagine the only issue of this change in the language can be the backwards compatibility; the most programmes written before this change, working with strings and arrays would compile as well with the change, e.g.:
Local Arr:Float [] = [ 1# , 2# , 3# , 4# ] DrawPoly ArrIt wouldn't matter that an array is now also a Collection, the code compiles just as well. However, a big problem is that this change would need two more keywords (I named them 'Array' and 'Collection' above, but those don't need to be the actual names), and if someone used previously these keywords as function or variable names, this person would get a lot of compiling errors. Therefore I suggest to add a special syntax to the top of the source files, indicating that these keywords aren't used as identifiers and can be therefore accessed from this code. It could look like
Strict 1.26or
SuperStrict 1.26If the compiler doesn't detect this at the top of the source file, it switches to a compatibility mode, that means whereever these two keywords appear in this source file they aren't seen as keywords, instead they're treated as normal identifiers for functions, types or variables.
Additional you could do this vice versa with Len: till now Len is a keyword indicating that the Len-operator is used. If the compiler detects a "Strict/SuperStrict 1.26" statement it doesn't treat Len as keyword anymore - Len is then a function sitting in the brl.retro module.
I know it would be a lot of work to implement this in the compiler, but the result of this change would really solve this and maybe some other issues. So you can see what the work is worth - how do you think about that?