Passing an array as a RETURNed parameter
I'm pretty sure this has been discussed before, somewhere, but I can't find it in a quick scan of the forum. According to my reading of the BBC BASIC specification this program ought to work - and it does in my BASICs (not through any specific coding to make it work, but simply because it arises from the normal operation of the interpreter):
ARM BASIC V: "Undimensioned array in line 20"
Matrix Brandy: "The dimensions of array a() have not been defined at line 10"
(ARM BASIC fails after the procedure has been called, Brandy before)
I don't see how this code breaks any 'rules' of BBC BASIC:
ARM BASIC's "Undimensioned array in line 20" doesn't make sense because it was DIMensioned inside the procedure and then RETURNed. Matrix Brandy's "The dimensions of array a() have not been defined at line 10" doesn't make sense because it's declared as a RETURNed parameter so there's no requirement that it should be defined.
10 PROC1(a()) 20 PRINT a(5) 30 END 40 DEF PROC1(RETURN a()) 50 DIM a(10) 60 a(5) = PI 70 ENDPROCHowever it doesn't work in ARM BASIC V or in Matrix Brandy, albeit that they fail in completely different ways:
ARM BASIC V: "Undimensioned array in line 20"
Matrix Brandy: "The dimensions of array a() have not been defined at line 10"
(ARM BASIC fails after the procedure has been called, Brandy before)
I don't see how this code breaks any 'rules' of BBC BASIC:
- Passing an entire array to a procedure is fine in BBC BASIC, with the syntax I have used.
- Passing an uninitialised variable to a procedure is fine, so long as it is declared as a RETURNed parameter (in that case it is created within the procedure).
- Dimensioning an array inside a procedure is fine, whether it is a LOCAL or global array.
ARM BASIC's "Undimensioned array in line 20" doesn't make sense because it was DIMensioned inside the procedure and then RETURNed. Matrix Brandy's "The dimensions of array a() have not been defined at line 10" doesn't make sense because it's declared as a RETURNed parameter so there's no requirement that it should be defined.
0
Comments
-
Richard_Russell wrote: »I'm pretty sure this has been discussed before
I can think of only two plausible reasons for the code I listed not working. Either (1) there is code in the interpreters specifically to stop it working, but why would a useful feature be blocked? or (2) arrays aren't passed to, and RETURNed from, procedures in the same way that scalar variables are. But why wouldn't they be, isn't that just extra work for no benefit?
Perhaps somebody other than Michael could reply, to prove that this forum really does have more members!0 -
Sorry, no, I've been rushed off my feet with work stuff and sorting things out for my kid.0
-
Richard_Russell wrote: »Perhaps somebody other than Michael could reply, to prove that this forum really does have more members!
I'm reading, and your reasoning looks correct to me, even though on first sight the program looked odd to me. But then you're an expert and I'm not. Whether the reasoning shows the way for Matrix Brandy to follow suit without too much difficulty is a question for others - probably for Michael!
It might be good to have an illustration here in this thread of the kind of useful library function you mention.
0 -
It might be good to have an illustration here in this thread of the kind of useful library function you mention.
For example suppose you have a set of library functions which are designed to work with a specific kind of file, let's assume an image file. You might have one function which opens the file, another which allows you read the colour palette from the file, another which allows you to read the image dimensions, another which reads a particular pixel etc.
Each of the functions which operates on that image file is going to need to know things like the image format, the image size, the bit depth etc. This information will typically be contained in a file 'header' of some sort. It would be hopelessly inefficient for each function to re-read the header, so you want some way of passing all that data around so it's readily available to each function.
Typically you might have a function which opens the image file and returns to the calling program an array containing all the relevant context information read from the header. Then each function operating on that image file gets passed that array, so it knows everything that it needs to know about the file. The calling program, however, knows nothing about the contents of that array.
To implement this kind of scheme in BBC BASIC you need a way for the calling program to pass an un-dimensioned array to the function which opens the file, within that function the array is DIMensioned and populated with the necessary data, and then returned to the calling program. That 'just works' in my BASICs, it never occurred to me that it wouldn't (despite the interpreter not having been specifically coded to support it) but it doesn't work in ARM BASIC or Matrix Brandy.
0 -
Richard_Russell wrote: »The concept of 'opaque structure' or 'opaque array' (and admittedly it's more generally applicable to structures than to arrays) allows multiple related library functions to share context
Object Oriented languages use exactly this technique (albeit using an opaque structure rather than an array) to pass the object to the individual methods so they have access to the shared object properties. BBC BASIC isn't Object Oriented, but my modern BASICs do have support for that paradigm via the classlib library, which relies on this working.0 -
Richard_Russell wrote: »arrays ... passed to, and RETURNed from, procedures in the same way that scalar variables are.
Apart from common sense suggesting that the design of the interpreter should be made much easier if they are, in fact this information is exposed in the documentation of the CALL statement.
CALL creates a 'parameter block' in memory in which each variable (or array) is represented by two values: a type and an address (pointer). These basically tell you everything you need to know about the object concerned.
The type values aren't consistent between different implementations (for example in my BASICs an array is flagged by setting bit 6, in Acorn's by setting bit 8) but it demonstrates a compatible representation of scalar variables and arrays.
Of course there is a 'slight' complication that Matrix Brandy doesn't implement CALL, but I assume it still uses the same type + pointer representation internally otherwise that would be very odd.0