14

For the 8-bit Microsoft derived BASIC interpreters (i.e. AppleSoft, Commodore, etc.) you define a variable by simply declaring it to have a value, e.g. A$ = "hello". When you no longer need the string around, you can wipe out it's value by doing a statement like A$ = "".

It has been years since I've studied the disassembly of AppleSoft BASIC, but I believe if you "wiped out" the variable, it didn't remove the variable as an entry in memory. Yes, the value of "hello" would eventually get garbage collected, but I'm wondering if A$ would live on in a variable lookup table of some sort. Of course, I would expect the NEW statement to wipe out all variables and tables, but that also erases the program in memory.

So the question is, does a variable which no longer has a value still have any footprint in RAM, or was the implementation clever enough to remove it and only return empty-or-zero values of variables that didn't exist in the variable lookup table?

4
  • RUN also cleared variable storage. Commented Aug 22 at 18:01
  • On your last paragraph: You'd rather not want to have variables with the value zero or a string that is empty removed when these are valid values - which they are. Commented Aug 22 at 20:18
  • 1
    @tofro - yes, empty and zero are valid values, but that is the behavior of (at least) AppleSoft BASIC. If I CLEAR and then PRINT X I will get zero as the language doesn't have a concept of NULL or NaN as far as I've ever seen over the years. Commented Aug 23 at 13:45
  • Worse, perhaps is what happens in Apple II BASIC and MAY perhaps happen in uS BASIC. I found this out the har way when trying to do machine language access to variables --> When you declared a variable value in the program the value ws stored in RAM IN the program code. If you changed the variable value the CODE IN RAM was altered. Now 45+ years on I can't remembered why this mattered and how I overcame it, but, it did and I did. Fading memory says that I assigned the variable in a manner that forced it to be in RAM proper rather than program RAM. Commented Aug 27 at 7:31

6 Answers 6

14

So the question is, does a variable which no longer has a value still have any footprint in RAM,

Yes, the table entry for a variable persist for the whole runtime of a program. Those tables are only made to be extended, never compacted.

It also doesn't make much sense otherwise, as the interpreter has no way to know if a variable will be used again further down the road. Even more, a zero length string is still a valid string. Same goes of course for numeric ones, as a value of Zero is still a valid value.


Details

So the question is, does a variable which no longer has a value still have any footprint in RAM,

Yes, they still occupy an entry in the variable table.

In applesoft all simple variables are stored in a single data structure reserving 7 bytes per variable. It holds the variable name (*1), variable type and for numeric variables it's value. For string variables it contains the string length and a string pointer.

That way an empty string variable is already reduced to the minimum.

or was the implementation clever enough to remove it

No, as there is no way to decide that.

Also, removing every variable that reaches zero at some point would mean the table has to be reorganized all the time. That is if the goal is to save space. That's moving memory around, wich is about the most costly operation there is on 8 bit CPUs.

On a side note, it would also remove one of the most potent ways of improving execution speed, which is defining variables in sequence of most common usage (*2).

and only return empty-or-zero values of variables that didn't exist in the variable lookup table?

Not to mention that each 'temporaty deleted' variable would incur the maximum access penalty when used again - as the whole table has to be searched to find out it's zero (*3).


Of course some of that could have been coped with by having the variable table sorted by name, so a halving search could be used, speeding up all access. Still management would increase execution time notable - the crux of a ad hoc variable declaration instead of compile time allocation.

Not to mention that we're talking about BASICs that had to fit into some 4..12 KiB ROM space. Not much room for such luxury.

Developer back then rather spend any available space for including more functions to simplify life - remember, having doing a computer a job is way more fundamental than having it doing the same job fast.


*1 - Or mor exact only the first two bytes, as only those are valid. The variable type is stored in the high bit of those bytes. That way integer, real and string variables can have the same name but still be different.

*2 - It was a common 'trick' to define most needed variables first in a program as that could lead to dramatic speed improvements. That way the most needed were found first (*3). See for example this program.

*3 - Any access to a variable is made by a linear search thru the variable table.

8
  • 1
    Some dialects of BASIC, including Microsoft's BASIC for the PC, included an "erase" command which could erase arrays. This required having code to move existing arrays downward in memory. BTW, I wonder if any consideration was given to having "ordinary" variables sit above arrays in RAM, to avoid having to relocate all arrays whenever an "ordinary" variable was added. Commented Aug 22 at 22:45
  • Regarding the life cycle of BASIC variables, it's a little known feature that you can DIM simple (scalar) variables and string variables without a subscript indicating an array length. If the variable hasn't been defined yet, this will place it in the variable list with a value of zero (string variables with a length of zero and pointing to $0000 for the content.) Notable exception: you can't dim FN variables, these are exclusively declared by the DEF command. Commented Aug 23 at 0:47
  • 2
    PS: This feature is particularly useful for defining an optimized lookup order. instead of going through all the actual assignments early on, you can have a statement like "DIM A, B, X, Y, X1, Y1, A$". This also separates the concerns of lookup order and value assignment, which may improve readability. Commented Aug 23 at 1:01
  • Also: "by the DEF command" – make this, "by the DEF keyword", which is probably the proper way to put it. :-) Commented Aug 23 at 1:10
  • 2
    @Dúthomhas True, that's the title, btu the OP also phrases his exact question in the last paragraph: "So the question is, does a variable which no longer has a value still have any footprint in RAM" I find it useful to read postings in full. Commented Aug 25 at 12:40
4

Applesoft BASIC has a CLEAR command to clear the variable area. "Clearing", however, can mean either removing or zeroing the variable. (And CLEAR can obviously not wipe a specific variable only - it's all or nothing) According to the AppleSoft manual, CLEAR

Zeroes all variables and stings. Resets pointers and stacks.

which doesn't really tell us much, even if the last sentence - somewhat contradicting to the first - seems to indicate the variable area is really emptied, rather than zeroed.

A quick glance into the re-engineered AppleSoft source code seems to indicate the variable area is actually wiped rather than "zeroed" - CLEAR calls a routine SETPTRS, which is also called on NEW and RUN so basically is creating a "blank plate".

3
  • 2
    Clear is more of a run-time restart than anything else. It was meant to have a way to recover from some errors. rarely used. Commented Aug 22 at 20:08
  • @Raffzahn CLEAR is like NEW, but leaves the program intact. It can obviously not wipe specific variables, but "a variable" is a subset of "all variables". Commented Aug 22 at 20:12
  • 1
    No need to argue. I'm pointing out what CLEAR was good for. And yes, a variable is a subset of all variables. THen again, it kinda blows if one wants to clear a specific variable and all are gone, doesn't it? :)) Commented Aug 22 at 20:28
4

does a variable which no longer has a value still have any footprint in RAM?

This seems to be without meaning, since the result of executing

A$ = ""

is a variable whose value is the empty string, not a variable with 'no value'.

Other languages may distinguish the case of 'no value', but even then they still distinguish between existence and non-existence of a variable.

2
  • To be precise, it will point into that location in the BASIC text (the empty string) and have a length of 0 (zero). Commented Aug 23 at 0:43
  • 2
    You are probably correct, but you are mixing language semantics with implementation details. An implementation is free to do whatever it wants. Commented Aug 23 at 12:20
3

"does a variable which no longer has a value still have any footprint in RAM..."

Once created, BASIC variables always have a value. For a string variable, the null (empty) string is a value no different to "a" or anything else.

BASIC cannot determine which string variables are wanted and which are unwanted by their value alone. If it did do so using your example, the following legal program in 'generic/nobodys BASIC' would give an error if just ENTER/RETURN was pressed at the INPUT:

INPUT A$
IF A$="" THEN LET A$="UNKNOWN"
PRINT "Hello,",A$

All variables can be deleted using CLEAR but that's not achieving what you want, nor was it intended for that purpose.

2
  • I don't get your last paragraph. Of course, CLEAR was intended to delete all variables, because that is what it does. Commented Aug 23 at 6:38
  • 2
    @tofro, no need to argue. I'm pointing out what CLEAR does wrt quoted question. It's perfectly clear. Commented Aug 23 at 7:51
1

Commodore 64 (BASIC V2) had the CLR command for this purpose:

The BASIC-Command CLR deletes all variables, arrays, data read position from DATA lines, defined functions (DEF FN), return addresses of subroutines (GOSUB) and the state of loops (FOR and NEXT) by releasing the space in BASIC RAM and on stack previously allocated for those structures. Furthermore the state of open files (OPEN) and possibly buffered data for devices like diskette or datasette of the associated files gets lost because the data is freed.

2
  • The question asks about removing a variable, not about resetting the entire workspace. Commented Aug 25 at 0:08
  • 1
    True. This is basically an extension of @tofro's answer. Also the question is a bit vague in wording: "Of course, I would expect the NEW statement to wipe out all variables and tables, but that also erases the program in memory.", hinting that they could also be interested in a method that wipes all variables but doesn't erase the program. Commented Aug 25 at 1:22
0

does a variable which no longer has a value still have any footprint in RAM

The question doesn't make sense, since there is nominally no way in standard BASIC to make a variable lose its value. It can only get assigned a different value, but never no value.

If you intended to ask whether a variable which is no longer referenced still has any footprint in RAM - think what it would do to immediate mode. Suppose you did:

LET A=5
Ok
PRINT A

What would you expect for an answer? If the BASIC had garbage collection for unreferenced variables, the A variable would cease to exist as soon as LET finished executing. Then, PRINT A would find no variable A, and would instantiate it with the default value of 0, print out that 0, then remove the variable.

The variables created in the immediate mode could be marked specially so that they would not be subject to garbage collection.

Editing and removing program lines would require modifications to the variable table, so those activities would become even slower than they already usually were. Normally, removing a line by typing <line number> <RETURN> would remove that line as follows:

  1. Program is scanned for that line number.
  2. End of the line is found.
  3. Everything past the end of line is memory-moved back by the removed line's length.
  4. End-of-program system variable is updated.

This could be painfully slow on long programs. With garbage collection of unreferenced variables, the process would look as follows:

  1. Scan program for line number.
  2. Scan the line. For every variable reference found, scan the variable table for said variable and decrease the reference counter there.
  3. Move the program back by the line length, update end-of-program variable.
  4. Scan the variable table. While scanning,
    1. Maintain a move_back counter, initially at zero.
    2. For a variable with zero reference count, increment move_back.
    3. For a variable with non-zero reference count, move it back in the variable table by the number of positions given by the move_back counter if its value is non-zero.
    4. Move to the next position in the variable table, resume at 2.

That's for BASICs that reference variables by name from the source code / tokenized code.

There are tokenizing BASICs that reference variable indices directly within the token stream, i.e. by pointing into or indexing the variable table entry rather than by name. E.g. BASIC II by Luxor from the ABC 800 series of computers.

There, this process would become even more complicated. Each modification of the variable table would require a rescan of the entire tokenized program to update each reference to variables that came after the now-removed variable. The equivalent of Python's del statement in such a BASIC would be O(M*N), where M is the program length, and N is the number of variables in the variable table.

There are improvements that would make it less painful, e.g. marking the variable table entry as unused rather than compacting the variable table. That way the memory would not be reclaimed immediately, but unused variable entries could get reused.

Luxor's BASIC II had function-local variables that used the end of the variable table like a stack, it was pretty neat in 1981 on a Z80 machine. It was so much faster and nicer to use than BASIC.COM and BASICA.COM from the same period.

2
  • 1
    People write interpreters that requiring 'scanning' source text? Has no-one heard of hashing? Commented Aug 27 at 1:31
  • You are aware that this question is limited to Microsofts BASIC as found on (most) 8 bit machines? (BTW, yes, the ABC 800's BASIC was a real nice thing - and for sure not 'standard'). Commented Aug 27 at 10:37

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.