Topics

Proposal to rationalise VDU variables

Richard Russell
 

I'm contemplating doing something drastic: making an incompatible change to BB4W (and indeed to BBCSDL subsequently)! I'd appreciate people's views on whether such an exceptional step can be justified.

Because of the way BBC BASIC's capabilities have grown over the years, anomalies have arisen in respect of the location of some 'system' variables. Specifically the 'cursor movement' flag (set using VDU 23,16...) and the 'line thickness' value (set using VDU 23,23...), which should both logically be part of the VDU variables structure @vdu{}, aren't. The cursor movement flag is currently at ?444 and the line thickness value at @vdu%?248 (in BB4W).

Apart from being 'illogical', not being part of the VDU variables structure has the practical consequence that in programs which deliberately save and restore this structure (e.g. banner.bbc, Ceefax.bbc, telstar.bbc and multiwin.bbc) these variables are not automatically saved as they should be. Some (but not all) of these programs deliberately save and restore the cursor movement flag separately, but none currently saves the line thickness value. Moving them into the VDU structure would fix this.

I have reluctantly accepted this situation in BB4W to date because of the compatibility implications of moving them. But BBCSDL has already set a precedent for moving the line thickness value (it is no longer at @vdu%!248, and indeed isn't even in the same place in 32-bit and 64-bit editions), and updating BB4W to v6.13a provides what might be the last ever opportunity for putting this anomaly 'right'.

So what are your views? If I don't fix this now, there will forever be frustration at the anomalies. But if I do there will definitely be programs that break (I know for sure that some programs set the line thickness using @vdu%!248=n because once upon a time it was the only way). Most likely the consequence will only be 'cosmetic' but it could be important, and such programs will need to be modified.

If I do make this change I will at least ensure that ?444 and @vdu%!248 become 'unused' locations, so that if any unmodified program does write to them no harm will be done.

Mark Moulding
 

This wouldn't affect any of my personal existing software, so of course I'd be in favor of the change.  Especially since any significant application will probably be mostly used as a compiled executable, so that existing production software won't be broken, it seems to me to be not much of a burden to update a clearly-documented change of this type for a new release.  (It was OK - on a much larger scale - for Python apparently, from 2.x to 3.x...)
~~

Mark Moulding

wilsr747
 

I would leave well alone, myself - but I don't any longer do much programming so probably do not count!

Rog

dredandy
 

Hi Richard,

I think that any change that improves consistency between BB4W and BBCSDL (and also improves consistency of the language itself) is important and very welcome. It is relatively little work to fix any programs that might break as a consequence. I think what you are proposing is a good idea.
 
I would also like to take this opportunity, while you are considering making changes to BB4W and BBCSDL in the interests of language consistency and cross-platform compatibility, to suggest that perhaps the indirection operator ']' be introduced into BB4W and BBCSDL (32-bit).
 
On the aforementioned 32-bit platforms that operator would function, in practice, as a 32-bit integer indirection operator (essentially an alias for '!'). The idea being that, ']' could in general be understood as an address indirection operator rather than specifically a 64-bit integer indirection operator.
 
I write a lot of data structures, and I use a function call to set and get pointers in order maintain cross-platform compatibility. However, by implementing ']' on all platforms as an address indirection operator, I think it would be a significant aid in writing cross-platform code, and might (dare I say should) improve the performance of that code where currently a function call is required to test for platform compatibility before executing code that uses the appropriate indirection operator. Further more, it would improve the elegance and readability of the language. For example, although it is not strictly necessary in BBC BASIC to use '==', I appreciate being able to use it because it makes code that much clearer. In the past, when writing 32-bit only code, I of course would use '!' to access data and address values within a data structure. It would be preferable, regardless of the platform, to be able to use a different operator symbol for address values.
 
I am also suggesting this because, if it is desirable and not too inconvenient to implement, it would not create any compatibility problems with existing programs, as far as I am aware.

Many thanks

Andy

Richard Russell
 

On Sat, Feb 22, 2020 at 05:34 PM, dredandy wrote:
I think that any change that improves consistency between BB4W and BBCSDL  is important
Of course initially it will make them less consistent with each other, but if I go ahead and make this change in BB4W it will be my intention to follow suit in BBCSDL before too long.

suggest that perhaps the indirection operator ']' be introduced into BB4W and BBCSDL (32-bit)

That's an interesting proposal, and not one that has been 'on my radar'.  My concern is that it would involve a change to the most crucial and central code in the whole of the interpreter, and inevitably slow absolutely everything down (if only slightly).  In particular every single variable lookup would be slower than it is now, by the time it takes to test for the ']' character (and decide that it isn't).

Do you genuinely feel that the advantage of supporting the ']' indirection operator outweighs slowing down every program?  I could make an attempt to estimate how much a typical program might suffer, if it helps.  If we do want to contemplate this it would probably be necessary to carry out a further consultation.

Let me know if you still think this is something worth pursuing and I will reach out for views on the forum.

Richard Russell
 

On Sat, Feb 22, 2020 at 06:17 PM, Richard Russell wrote:
I could make an attempt to estimate how much a typical program might suffer, if it helps. 
Having done a quick benchmark comparison, I must admit that there is no statistically significant penalty in testing for the 64-bit indirection operator, at least not with the Core i7 CPU I used for the test.  It's possible that execution of that instruction is being overlapped with something else and therefore happens 'for free'.  Anyway, it doesn't look as though there's any good reason not to add that feature in the upgrade.

Richard Russell
 

On Sat, Feb 22, 2020 at 05:34 PM, dredandy wrote:
On the aforementioned 32-bit platforms that operator would function, in practice, as a 32-bit integer indirection operator (essentially an alias for '!'). The idea being that, ']' could in general be understood as an address indirection operator rather than specifically a 64-bit integer indirection operator.
Although I can see where you are coming from, I am certain that making the ] operator an alias for ! would be a mistake and something we would forever regret.  The reason is simple: if ] performed 32-bit indirection what operator would perform 64-bit indirection?!  We really struggled to find a suitable symbol for 64-bit indirection, and although 32-bit editions of BBC BASIC don't use 64-bit addresses (pointers) they do support 64-bit data values - even Matrix Brandy does - so 64-bit indirection is something that could definitely be useful for storing such values in memory.

I write a lot of data structures, and I use a function call to set and get pointers in order maintain cross-platform compatibility.

From the context I assume those "data structures" use blocks of memory (perhaps allocated with DIM) and indirection operators to access them.  That is indeed the 'traditional' (and once upon a time only) way to implement flexible data structures in BBC BASIC, but BBC BASIC for Windows and BBC BASIC for SDL 2.0 support 'proper' structures with named members, sub-structures and arrays-of-structures.  Can you not implement your data structures that way?  Admittedly you are still likely to need platform-specific code to modify structure pointers (which may be 32-bits or 64-bits) but not to handle their members.

There is no precedent in BBC BASIC for pointer types, operators or functions (i.e. ones which operate on 32-bit values in 32-bit editions and 64-bit values in 64-bit editions).  Perhaps you can describe in more detail a practical example of when you would have found such support useful, in case I can suggest an alternative approach.

dredandy
 

Hi Richard,
 
Sorry for the delayed reply, and thanks for looking into my suggestion.
 
> Although I can see where you are coming from, I am certain that making the ] operator an alias for ! would be a mistake and something we would forever regret.
 
You might well be right, and I think I am now tending to agree, though I don't feel 100% certain about the best way to implement the ] operator on 32-bit platforms. I have never missed the absence of 64-bit integer indirection on those platforms, mainly because most data sets (at least all that I have worked with) don't need representing by numbers larger than 2 billion.
 
But, having said that, even implementing the ] operator as 64-bit integer indirection across all platforms, will still facilitate cross-platform address indirection to a large extent, assuming that 64-bit values are used where applicable (in propitiatory data structures) to hold address values. Despite loosing the memory footprint advantage, this is something that I have started doing anyway for the sake of cross-platform design, and as with my past concerns about speed, my concerns about memory usage, while still being a consideration, are less about minimizing the footprint, and more about striking a better balance between code design, memory usage, and speed. 
 
> Perhaps you can describe in more detail a practical example of when you would have found such support useful, in case I can suggest an alternative approach.
 
I make as much use of BBC BASIC's structures as I can, and I very much appreciate them. However I was referring to data structures more broadly, E.g: linked lists, tries, digraphs etc., and of course, I often use BBC BASIC's structures to define nodes (though not always, because some nodes are so simple - perhaps just a pointer and single data value - such that the overhead of 'formally' accessing the data block is not worth it). That suggests, as you said, perhaps the only limitation of fixing the ] operator as 64-bit integer indirection, which is it retains the need for platform testing when setting variable header address values E.g:
 
IF X64% ]^a%() = p%% ELSE !^a%() = p%%
 
and instead of something like this:
 
](^s{} + SIZE_OF_PTR) == p%%
 
we stick with something like this:
 
IF X64% ](^s{} + 8) = p%% ELSE !(^s{} + 4) = p%%
 
The platform testing is not elegant, but as I think about it, there is not much in it, and having the ] operator provide consistent 64-bit integer indirection across all platforms is both helpful for data (and still in many circumstances, cross-platform pointer) indirection.
 
I agree :-)
 
Many thanks
 
Andy

J.G.Harston
 

dredandy via Groups.Io wrote:
On the aforementioned 32-bit platforms that operator would function,
in practice, as a 32-bit integer indirection operator (essentially an
alias for '!'). The idea being that, ']' could in general be
understood as an address indirection operator rather than specifically
a 64-bit integer indirection operator.
ooooo, I wouldn't do that. ! explicitly means 32 bits, ] explicitly means
64 bits. The principle of least surprise, I wouldn't expect !A% to
access 16 bits just because the BASIC is running on a PDP11.

--
J.G.Harston - jgh@... - mdfs.net/jgh

J.G.Harston
 

On 23-02-2020 11:37, Richard Russell wrote:
Anyway, it doesn't look as though there's any good reason not to add
that feature in the upgrade.
If adding ] to mean 64-bit indirection on all platforms, yes go ahead.

But the OP was talking about adding ] to 32-bit platforms to perform
32-bit indirection as an alias for !. That I would advise against.

--
J.G.Harston - jgh@... - mdfs.net/jgh

J.G.Harston
 

dredandy via Groups.Io wrote:
IF X64% ](^s{} + 8) = p%% ELSE !(^s{} + 4) = p%%
But for that, if ] existed on all platforms, you'd use something like:

](^s{} + offset) = p%%

and set offset beforehand.

I can't think of an example right now, but I've seen loads of code that
does:

IF NOT(special_case) THEN do_thing ELSE manually_do_stuff_that_replicates(do_thing)

that should just be plain:

do_thing

and stuff like:

IF thing THEN do(x) ELSE do(y)

where x and y are functions of thing and could be simply:

do(calculate_something_from(x))


--
J.G.Harston - jgh@... - mdfs.net/jgh

Richard Russell
 

On Tue, Feb 25, 2020 at 10:31 PM, J.G.Harston wrote:
But the OP was talking about adding ] to 32-bit platforms to perform
32-bit indirection as an alias for !. That I would advise against.
Me too.  Although several programming languages do support a 'pointer' or 'address' data type, there is no precedent for it in BBC BASIC.  It's really only of value when the entire panoply of variables, operators and functions of that type is available; for example in C the 'increment' (+=) operator knows that on a 64-bit platform it must add 8 whereas on a 32-bit platform it must add 4.  Simply having a 'pointer indirection' operator without any other support is unlikely to be sufficient to eliminate platform-dependent code, in which case you might just as well not have it.

Richard Russell
 

On Sun, Feb 23, 2020 at 04:20 PM, dredandy wrote:
IF X64% ](^s{} + 8) = p%% ELSE !(^s{} + 4) = p%%
My 'solution' to this, albeit that it involves a significant performance hit if speed is critlcal, is to offload the platform-dependence to a procedure (here from dlglib.bbc):

      DEF PROC_setptr(RETURN d{},p%%)
      IF INKEY(-256)=&73 IF @platform% AND &40 ](^d{}+8)=p%% ELSE !(^d{}+4)=!^p%%
      ENDPROC

Now one can simply do PROC_setptr(s{}, p%%) which I think is quite elegant.

Richard Russell
 

On Sat, Feb 22, 2020 at 05:34 PM, dredandy wrote:
On the aforementioned 32-bit platforms that operator would function, in practice, as a 32-bit integer indirection operator (essentially an alias for '!'). The idea being that, ']' could in general be understood as an address indirection operator rather than specifically a 64-bit integer indirection operator.
I think we now all agree that this is not a good idea, but I have remembered that there is a kind of 'pointer' or 'address' data type in BBC BASIC for SDL 2.0.  If you are writing cross-platform code and you declare two structures, one for 32-bits and one for 64-bits as follows:

      IF @platform% AND &40 THEN
        DIM struct{addr%%}
      ELSE
        DIM struct(addr%)
      ENDIF

Then subsequently in your program you can access that structure member as struct.addr% (with a single percent sign) always, even when running in 64-bits!  This 'feature' came about almost accidentally as a result of wanting system variables like @memhdc% and @hwnd% also to be 64-bits when running on a 64-bit platform, and when I realised that it could be useful I kept it!