uBound: Get the dimension of an array

Code tips and tricks for beginners
Post Reply
User avatar
Fernando Perez
Posts: 378
Joined: Mon Feb 15, 2021 10:09 pm
Location: Santander (Spain)
Has thanked: 195 times
Been thanked: 267 times

uBound: Get the dimension of an array

Post by Fernando Perez »

I can't find a function that returns the dimension of an array.
I have written this SUB, in which I have taken the opportunity to see the different ways that Annex allows for using loops.
You can comment/uncomment the different modes, the result is the same in all cases.

Code: [Local Link Removed for Guests]

' Intercept errors 
numError =  0
onError goto wrong

option.base 1
dim words$(9)

dimension = 0
uBound words$(), dimension
wlog dimension

END

' ============================
SUB uBound array$(), dimension
' ============================
LOCAL i, c$

' MODE 1:
'  while numError <> 5
'    incr i
'    c$ = words$(i)
'  wend

' MODE 2:
'  do while numError <> 5
'    incr i
'    c$ = words$(i)
'  loop 

' MODE 3:
'  do until numError = 5
'    incr i
'    c$ = words$(i)
'  loop 

' MODE 4:
'  do
'    incr i 
'    c$ = words$(i)
'  loop while numError <> 5  

' MODE 5:
  do
    incr i
    c$ = array$(i)
  loop until numError = 5

  dimension = i - 1
  numError = 0

END SUB  

'-------
 wrong:
'------- 
  numError = BAS.ErrNum
return

BeanieBots
Posts: 361
Joined: Tue Jun 21, 2022 2:17 pm
Location: South coast UK
Has thanked: 197 times
Been thanked: 115 times

Re: uBound: Get the dimension of an array

Post by BeanieBots »

As your code needs to dimension the array in the first place, I'm not sure why you would need such a function.
Maybe if Annex supported ReDim it might have a use but even then it would not be a major task to keep track of its dimensions.
Maybe I miss something?

ArraySize = X
Dim MyArray(X)
For N = 0 to X
do something to MyArray(N)
Next X
User avatar
Fernando Perez
Posts: 378
Joined: Mon Feb 15, 2021 10:09 pm
Location: Santander (Spain)
Has thanked: 195 times
Been thanked: 267 times

Re: uBound: Get the dimension of an array

Post by Fernando Perez »

In this specific case, for me it is very obvious:
dim words$(9)
If I then use this array in a subroutine, how does the subroutine know what the dimension of the array is to execute its processes?

But in any case, in Annex you can resize an array.
Annex help says:
"The arrays can be re-sized using the same DIM command.
In this case all the existing elements will maintain the previous value except the new elements that will be initialized at 0 or null string."


It is true that on very rare occasions you will need to resize an array, but if that were the case and, since Annex allows it, an instruction similar to the uBound of traditional Basics is essential if the new size is the result of a function, subroutine or calculation process.

Please analyze this:

Code: [Local Link Removed for Guests]

numError =  0
onError goto wrong

option.base 1
dimArray = 0

dim a(9)
uBound a()
wlog "Current dimension = "; dimArray
fillArray a()
seeArray a() 

while 1
  pause 3000
  dim a(rnd(25)+1)
  uBound a()
  wlog "Current dimension = "; dimArray
  fillArray a()
  seeArray a()
wend
  
END

' ================
SUB uBound array()
' ================
LOCAL i, c
  dimArray = 0

  do
    incr i
    c = array(i)
  loop until numError = 5
  dimArray = i - 1

  numError = 0

END SUB  

' ===================
SUB fillArray array()
' ===================
LOCAL i
  
  uBound array()
  
  for i = 1 to dimArray
    array(i) = i
  next i
  
END SUB

' ===================
SUB seeArray array()
' ===================
LOCAL i
  
  uBound array()
  
  for i = 1 to dimArray
    wlog array(i)
  next i
  
END SUB

'-------
wrong:
'------- 
  numError = BAS.ErrNum
return

BeanieBots
Posts: 361
Joined: Tue Jun 21, 2022 2:17 pm
Location: South coast UK
Has thanked: 197 times
Been thanked: 115 times

Re: uBound: Get the dimension of an array

Post by BeanieBots »

I don't dissagree, however, as you point out, Annex can ReDim by simply re-using the Dim command.
Dim can also use a variable as its argument.
I think it is still possible to achieve your desired effect by using a variable for the dimension and recalculating that variable within your subroutine/function and then executing another Dim(ArraySize).
eg.

ArraySize = 9
Dim a(ArraySize)
'uBound a() would return 9. So would ArraySize

ArraySize = ArraySize + 1 'result of function to calculate new dimension
Dim a(ArraySize) 'ReDim
'uBound a() will now return 10 and ArraySize is also 10

It might be nice to have uBound but I don't think it is essential.
Maybe I still miss something?
User avatar
Fernando Perez
Posts: 378
Joined: Mon Feb 15, 2021 10:09 pm
Location: Santander (Spain)
Has thanked: 195 times
Been thanked: 267 times

Re: uBound: Get the dimension of an array

Post by Fernando Perez »

Actually, you are right. If we are careful to previously store in a variable the value that we want to have the dimension of our array, we can always consult that variable and know the dimension.

Your reasoning has made me think about this whole matter.
And I have wondered why the uBound instruction or some equivalent exists in so many programming languages? This intellectual effort would be absurd if it were superfluous.
I'm thinking about Visual Basic, VBScript, VB.NET, C#, C++, Java, Python, etc. Without forgetting QBasic. :lol:

It may be that some of these languages allow the array to be resized from within a subroutine, not just from the main process. Of course, Annex doesn't allow it. What's more, it produces strange results:

Code: [Local Link Removed for Guests]

numError =  0
onError goto wrong

option.base 1
dimArray = 0

dim a(9)
uBound a()
wlog "Current dimension = "; dimArray
fillArray a()
seeArray a() 

reDim a(), 24
uBound a()
wlog "New dimension = "; dimArray
fillArray a()
seeArray a() 

END

' ================
SUB reDim array(), newDim
  dim array(newDim)
END SUB

' ================
SUB uBound array()
' ================
LOCAL i, c
  dimArray = 0

  do
    incr i
    c = array(i)
  loop until numError = 5
  dimArray = i - 1

  numError = 0

END SUB  

' ===================
SUB fillArray array()
' ===================
LOCAL i
  
  uBound array()
  
  for i = 1 to dimArray
    array(i) = i
  next i
  
END SUB

' ===================
SUB seeArray array()
' ===================
LOCAL i
  
  uBound array()
  
  for i = 1 to dimArray
    wlog array(i)
  next i
  
END SUB

'-------
wrong:
'------- 
  numError = BAS.ErrNum
return

image.png
I do not know what to think.
You do not have the required permissions to view the files attached to this post.
BeanieBots
Posts: 361
Joined: Tue Jun 21, 2022 2:17 pm
Location: South coast UK
Has thanked: 197 times
Been thanked: 115 times

Re: uBound: Get the dimension of an array

Post by BeanieBots »

[Local Link Removed for Guests] wrote: [Local Link Removed for Guests]Sat Sep 30, 2023 2:32 pm ...
And I have wondered why the uBound instruction or some equivalent exists in so many programming languages? This intellectual effort would be absurd if it were superfluous.
...
There are many such commands which were not part of the early versions of BASIC. I think they came in later with the poularity of more structured programming styles. Also, the use of variable scopes such as Global, Local and referenced. In general, the use of global variables is frowned upon almost as much as the use of 'goto' and to hold the array dimension as a global would be required so that it could be accessed by any routine that MIGHT require it.
I think the same argument could be used about structures such as For/Next, Do/Loop, While/Wend and Select/Case. The same results can all be acheived by using If/then/goto and a variable. So, in my opinion, it is about structured and more readable code which is a whole discussion in its own right :roll:
User avatar
Fernando Perez
Posts: 378
Joined: Mon Feb 15, 2021 10:09 pm
Location: Santander (Spain)
Has thanked: 195 times
Been thanked: 267 times

Re: uBound: Get the dimension of an array

Post by Fernando Perez »

I think you have reached the heart of the matter.
I have studied that throughout history linear programming, structured programming and object-oriented programming were used.
I believe that global variables are a latent danger, a time bomb that when our program grows too large, ends up exploding.
For this reason, and although I suspect that Annex internally works with OOP, I try to adjust to the structured one in "serious" projects, dividing the program into small blocks or SUBs (since Annex does not allow functions created by the user) and using massive LOCAL variables, (which are eliminated when exiting the SUB) and avoiding, if possible, the use of global variables.

And here another problem arises, some languages allow you to choose whether the parameter is passed by value or by reference. It seems that in Annex always by reference. A danger, but a way to emulate a real function.

My sole purpose was to allow a SUB to determine, by itself, the dimension of an array, which may have been modified at another point in the program.
I have used the same method (dirty but effective) of intercepting the ERROR object to find out when the DATA of a READ runs out.

And I also agree with your IF THEN, many of the instructions in a language are just for the convenience of the programmer. Give me a single MID$ and I can do anything with a string of characters. ;)
BeanieBots
Posts: 361
Joined: Tue Jun 21, 2022 2:17 pm
Location: South coast UK
Has thanked: 197 times
Been thanked: 115 times

Re: uBound: Get the dimension of an array

Post by BeanieBots »

Indeed, which is the "correct" way to write software? What is the "best" language to use? (ans. Annex RDS. Obviously ;) )
The problem with the above questions is that they depend on the application and to some extent the user.
I come from an era where RAM was at a premium and not a single byte was ever wasted. A fast clock was anything over 1Mhz.
These limitations determined how the software NEEDED to be written. "Good" software was that which used the least resource and/or ran the fastest.
To acheive those goals also required a good understanding of how the language was interpreted/compiled into machine code.
Now it is more about structure and even aesthetics. This ends up with the answers being a moving goal. :?
Anyway, as long as we are all having fun......
Stuart
Posts: 138
Joined: Fri Feb 19, 2021 7:46 pm
Has thanked: 5 times
Been thanked: 20 times

Re: uBound: Get the dimension of an array

Post by Stuart »

Fully agree. Oh the days of coding in hex. Only for small things fortunately. But the aspect you don't mention is maintenance and reliability. Good code these days has to be reliable and easy to update (everything we touch has software in it of course and it had better work). More important than squeezing in a last byte. That is where structured code comes in (and structured reviews processes). If you can't understand it six months later then it fails. Not for your hobby gadget obv. but for useful things, even if only one-offs. I have code running at home that has been running for over a decade. I rarely have to change anything but if I do I had better be able to understand it. And as for safety-critical systems, well fortunately I don't have to worry about them.
BeanieBots
Posts: 361
Joined: Tue Jun 21, 2022 2:17 pm
Location: South coast UK
Has thanked: 197 times
Been thanked: 115 times

Re: uBound: Get the dimension of an array

Post by BeanieBots »

You make a very good point about maintenance and reliability.
Documentation is key. I too have several pieces of kit that have run for several decades. Just like flash memory that has had too many writes, my own memory is starting to fail. If it were not for the comments, it would take me ages to reverse engineer what was going on. Also, these days, projects often have many authors and each contribution needs to work reliably with each other.
I have spent a good few years in the medical industry on both hardware and software. It's an absolute nightmare and badly miss-understood.
I spent a few years on the safety commitee. The most scary time of my life!
(it's mainly about butt covering and little to do with safety)
Your mention of safety-critical systems made me laugh because it reminded me of some absolute howlers that I've witnessed.
I can't give too much detail for obvious reasons but here are two.

Example 1.
If value > X then do something. 'Comment: Take corrective action.
If value > X then do something. 'Comment: Repeat detection in case first attempt fails.

Seriously, I found those two straight after each other in a piece of code.

The second example was more about how two pieces of kit 'talked' to each other.
One was the main controller (made by company X) and the other was a very lethal business end (made by company Y).
The two communicated via RS232.
All had been working well for several years until one day a unit was installed in France and the lethal bit failed to shut down when told to.
This took a while to fault-find but the findings were unbelievable.
The French cutomer had just installed the recently released French language pack when the life threatening event occured.
The reason:-
To terminate the process, the controller sent the ascii characters STOP. The (now French) business end was expecting FIN.
How that control system ever passed any safety standards is totally beyond me. For starters, a stop command should never be required, it should be a continuous stream of 'keep going'. ASCII words should NEVER be used for control. There are internationally recognised control codes for that.
I could keep going but I won't bore you all. It just astounds me how such things can not only get created but also get past design review and "expert" certification. Mindblowing :x
Rant over.
Post Reply