View Full Version : For discussion: simplified UDT / array of UDT initialization.
Petr Schreiber
20-08-2011, 20:21
Looking at Zak's code (http://www.thinbasic.com/community/showthread.php?11317-thinbasic-helicopter&p=84342#post84342), one idea from the past returned to my head - simple UDT initialization.
Lets take a classic case of UDT for vector:
Type Vector3D
x As Single
y As Single
z As Single
End Type
Dim myVector As Vector3D
Now, we can initialize the variable in two ways (leaving aside hacks ;)):
Way #1
myVector.x = 1
myVector.y = 2
myVector.z = 3
Way #2
With myVector
.x = 1
.y = 2
.z = 3
End With
Both are easy to understand, but also quite lenghty.
In past years I suggested to make possible something like:
myVector = (1, 2, 3)
Eros had good note, that this way of initialization is potentially dangerous, as it heavily depends on order of definition of UDT members. If you, for example during code cleanup, rearrange the order of UDT members, it immediately makes code damaged.
This time, I have slightly modded proposal, what about this syntax:
myVector.x,y,z = (1, 2, 3)
This way:
You get shorter form, still clear
Possibility of member mismatch is low, as you explicitly specify which members you want to initialize (in this case x, y, z in order as written)
It would allow arbitrary stunts, such as filling only the members listed -> myVector.x,y = (1, 2) ' -- Leaves z untouched
The brackets might seem redundant, but would be useful for initializing arrays of UDTs:
Dim myVectors(3) As Vector3D
myVectors().x,y,z = (1, 2, 3), (4, 5, 6), (7, 8, 9)
Only problem I see now is performance - for sure this won't be fast, as parser has to check type for each member in the sequence, to get the value. But from my side this is something I could live with, as the comfort it provides and the selfdocumenting factor seem to be the thing I would use this for.
I would be curious about your opinion on this proposal. I did not posted this in the Support as new Suggestion issue, as I wanted to discuss it first with others.
Do you see any weak points in this approach (like my original old proposal indeed had?). Would you like to see something like this implemented?
Thanks,
Petr
ErosOlmi
20-08-2011, 20:39
Petr,
because I noted zak's code too ... I was 100% sure you would have revamped that idea :D
I like very much your new concept. The problem is that it is not so easy to implement.
But let's talk about it a little more, in the meantime I will think about how to implement because in zak's code the main UDT contains an array so the solution must work on whatever nested level of arrays: array of an UDT that contains another UDT that contains an array, .... ans so on.
Ciao
Eros
Charles Pegge
21-08-2011, 08:03
Welcome back Eros.
MultiAssign proves to be very useful for filling simple structures, like vectors and arrays of vectors, and also arrays of primitives.
in Oxygen I use '=>' or '<=' notation. This is much easier for the parser than plain '='.
Arrays can be filled from any index point like this:
a[30]<=2,4,6,8,10 ...
Outer brackets must be used when assigning within a dim statement
dim as a[100]<=(2,4,6,8,10)
With vector arrays, I don't support inner brackets, tabular layout is better.
type LabelledPoint single x,y,z, string s
dim as LabelledPoint v[100]
v<=
0,1,2,"point A",
0,3,4,"point B",
1,1,2,"point C",
1,3,4,"point D"
Complications like arrays inside structures are not directly supported. The programmer must use overlays mapped to these internal arrays instead. Unions are another hazard. But in the cause of clean programming I recommend these difficult cases be cheerfully ignored :)
Charles
John Spikowski
21-08-2011, 09:49
myVector.x = 1
myVector.y = 2
myVector.z = 3
I find using associative arrays in ScriptBasic easier to use.
This is simulating a structure using labels as indexes to the array.
myVector{"x"} = 1
myVector{"y"} = 2
myVector{"z"} = 3
In this case x,y,z are variables (numeric or string) that define the index of the array.
x = 0
y = 1000000
z = "aBc"
myVector{x} = 1
myVector{y} = 2
myVector{z} = 3
ErosOlmi
21-08-2011, 09:59
---Charles
your method is clear and elegant but, as Petr mentioned above, it is risky because if the defined TYPE change the order of the elements programmer has to change all assignments accordingly otherwise subtle errors can be just around the corner.
---John
The problem is that associative arrays are not real memory structures that can be passed to API functions when requested but they are more like hash tables with key/data pairs.
And in that structures (associative arrays/hash tables) memory is not allocated continuously but randomly.
Thanks to all for this discussion.
Going on thinking ...
John Spikowski
21-08-2011, 10:20
The problem is that associative arrays are not real memory structures that can be passed to API functions when requested but they are more like hash tables with key/data pairs.
And in that structures (associative arrays/hash tables) memory is not allocated continuously by randomly.
I feel that a Basic language should interact with the user at the most simplest and highest level. The complexity of API interfacing should be done within an extension module. I can pass a C based extension module a ScriptBasic array variable and build whatever structure needed to interface with another library within the extension module. That is why it is important that the core Basic have a API of it's own to make interfaces seamless.
Petr Schreiber
21-08-2011, 10:57
Hi John,
having UDTs directly manipulable in ThinBASIC, there is no "API complexity" involved. I declare UDT, fill it, pass it to DLL function without any conversion or layer between. Job done :)
The only thing I would like to see improved (in specific cases), is the filling from code described in the first post.
What you describe is interesting, but it would not be suitable for my cases of use, that is interfacing to OpenCL, CUDA and OpenGL from thinBasic. I need to stay low level, converting huge hash tables to structures passable to DLL would eat too much time for me in these situations.
I know the approach you are talking about from Python, it is an option (especially in typeless languages), but I am not interested to see something like this in ThinBASIC at the moment.
Petr
ErosOlmi
21-08-2011, 11:57
Statically typed languages seems revamping over dynamically typed ones.
http://www.tiobe.com/content/paperinfo/tpci/images/history_paradigm_type system.png
Source: http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
(http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html)
John Spikowski
21-08-2011, 12:18
What you describe is interesting, but it would not be suitable for my cases of use, that is interfacing to OpenCL, CUDA and OpenGL from thinBasic. I need to stay low level, converting huge hash tables to structures passable to DLL would eat too much time for me in these situations.
In a previous code challenge, the ScriptBasic SPLITA directive split all the words in the Bible (1.4 million element array) in less than a second. I'm sure passing a SB array and having a C based SB API function convert it to a structure shouldn't be that costly.
Charles Pegge
21-08-2011, 13:22
Types are a major issue in programming. To get good performance you need to end up with types that the processor can handle directly. I found It is in fact possible to have typed and type-less directly available in the same language at least for primitives. To support this, the compiler/interpreter must provide automatic conversion between all the basic types used in an expression and then convert the result back to the correct form for variable assignment. This is hard work for the interpreter but nice for the user, especially for casual programming, where you want a quick result from a one-off program.
Coming back to Multi-Assign. I agree it is not without its hazards, if the order of elements is changed. It is most suitable for well known structures like vectors, complex numbers, matrices and dictionaries. I think it is also safe to use within class constructors, where they are usually nearby on the page to the class structure definition.
Charles
John Spikowski
22-08-2011, 04:41
This is hard work for the interpreter but nice for the user, especially for casual programming, where you want a quick result from a one-off program.
Actually Basic is the language of choice for one-off programming. It's probably the reason Basic is still around today. I'm counting on that theory and promoting ScriptBasic as the new GWBASIC for all platforms.