18

I do not understand line 80 of the short Applesoft BASIC program below. Didn't even know it was possible to have a single instruction be T=C/2=INT(C/2). Naturally, I tried breaking this line up / various dissections, all of which broke the program and didn't help me learn what this is really doing.

10  S=4
20  HOME : GR
30  FOR C=0TO15 : COLOR=C
40  FOR X=0TO1
50  VLIN 0,39 AT X+S
60  NEXT X
70  HTAB S+1 : VTAB 21+T : PRINT C;
80  T=C/2=INT(C/2)
90  S=S+2
100 NEXT C

Would appreciate learning from everyone's collective knowledge. When I get back to my big computer, I will cite the Apple II, IIe 'graphics' book where I found this low-res colorbar BASIC program.

5
  • 20
    Apparently, the two = symbols are parsed differently: the first as assignment and the second as equality test. Here, C would have used == for the latter.
    – Erik Eidt
    May 29, 2021 at 12:56
  • 1
    I first learned about boolean values in Applesoft by reading Beagle Bros programs. I don't think this behavior is documented in the Apple manuals. Multiplication can be handy, e.g. Y = (x > 7) * 10 will set Y to 0 or 10 based on the value of X. You can do a similar thing in C, though you have to be careful with older implementations.
    – fadden
    May 29, 2021 at 14:46
  • This seems to be COLOR DEMO 2, distributed on a tape bundled with the Apple II kit, at least judging by the output: the Apple II BASIC manual contains an identical screenshot (p. 32). May 30, 2021 at 7:58
  • 2
    not having distinct equality and assignment operators was a mistake.
    – hanshenrik
    May 31, 2021 at 11:06
  • 1
    Having only one = operator does mean that you can't use some constructs popular in other programming language like multiple assignment (a = b = 0) or assignments as part of loop conditions (while ((c = f()) >= 0)), but these can be easily worked around.
    – dan04
    Jun 8, 2021 at 23:49

3 Answers 3

31

Explaining what this line does is easy enough: it checks if C is even by dividing it by 2 and comparing the result to its floor, then stores the result of the comparison in the variable T. Comparisons are expressions like any other: they return a non-zero value (in the Applesoft dialect, 1) if the relation holds and zero otherwise. The IF statement evaluates an expression, and if it returns non-zero, executes the statement given after the THEN keyword. The line can thus be re-written like this:

T = (C/2 = INT(C/2))

or this:

T = 0 : IF C/2 = INT(C/2) THEN T = 1

and remain functionally the same.

Interestingly (as @another-dave points out), it was not always a feature of BASIC that relational operators could appear in any expression. The original Dartmouth BASIC did not allow it: the fourth edition manual (1968) defines a ‘formula’ to contain arithmetic operations only (§1.2, pp. 11–15), while an IF statement could perform a single comparison between two such ‘formulas’ (§1.2, p. 15; §1.7.5, p. 35). There were no logical connectives like AND, OR or NOT either. Dartmouth BASIC also included simultaneous assignment to multiple variables in a single statement: LET A = B = 2 would assign 2 to both A and B (§1.7.1, p. 33).

One of the earliest BASIC dialects that unified relational and arithmetic expressions was HP Time-Shared BASIC (1976). Doing so introduced a grammar ambiguity with multiple assignment, resolved in the manual as follows (‘LET Statement’, p. 11-46):

The rule that the equal sign (“=”) is an assignment operator only holds as long as numeric variables occur in the replacement list. If a numeric constant appears, followed by an equal sign, that equal sign is treated as a relational operator. For example, in A=2=B the first “equal sign” (=) is treated as an assignment operator and the second is treated as a relational operator.

(Presumably parentheses would also do the trick.)

Apple’s Integer BASIC (1977) followed suit in unifying arithmetic and relational expressions (pp. 56–58 in the manual), though it omitted multiple assignment. Microsoft dialects (1975) did similarly, though in the latter truth was usually represented as −1; this allowed logical connectives to perform double duty as bitwise operators. In those dialects, the ambiguity is instead resolved by the strict dichotomy between statements and expressions: if an = appears in statement position, it means assignment, while in expression position it refers to comparison. As lone expressions are not statements, unlike for example in C, the meaning of = is unambiguous.

2
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Chenmunka
    May 30, 2021 at 15:13
  • Applesoft is a Microsoft variant, but one which is explicitly modified to make comparisons yield 1 rather than -1, and make AND, OR, and I think NOT treat all non-zero values as 1, in the same irksome manner as C's short-circuit operators.
    – supercat
    Mar 7, 2022 at 16:46
12

The line in question is T=C/2=INT(C/2)

The first '=' is a variable assignment.

The second '=' is part of the expression and is an equality test.

The expression returns a boolean result, which is stored in T. The expression means 'is it true that C/2 is equal to the integer result of C/2'. In other words, is C a multiple of 2.

The values used for Boolean 'true' and 'false' vary between programming languages but are often the integer values 0 and 1.

A trick I saw along the same lines in an early BASIC was the line A=A=0.

This would toggle A between 0 and 1. If A was 0, then the Boolean test expression A=0 returned 1. If A was 1, then A=0 returns 0.

This is a compact and space-saving form in machines tight for RAM. But these days, clarity is far more important in the generously-memoried systems we're using or embedding.

4
  • 1
    A=A=0 more commonly toggles between 0 and -1, though on Sinclair BASIC it does 0 & 1.
    – scruss
    May 29, 2021 at 19:08
  • 2
    @scruss In ZX81 BASIC I would write LET A=NOT A anyway, as that only takes 5 bytes, which is less than the 7 bytes simply for the numeric constant 0.
    – Neil
    May 31, 2021 at 13:28
  • @Neil why is the numeric 0 7 bytes?
    – phuclv
    Mar 12, 2022 at 10:21
  • 1
    @phuclv In ZX81 BASIC (which isn't exactly fast), interpreting numbers from source (i.e. VAL) is very slow, so when the program is edited all numeric constants are suffixed by a marker byte and then the five bytes of the internal representation of the constant. When the program is executed, the interpreter simply skips ahead to the marker byte and reads the value. (LIST also knows to skip the marker byte and constant.)
    – Neil
    Mar 12, 2022 at 10:28
-1

Line 80 appears to be equivalent to the PHP short logic example in the following small program to output from a function;

<?php

function ternary ($C) {

$T = ( is_int( $C / 2 ) ) ? 1 : 0 ;

return ($T);

}

echo ternary (0);

echo ternary (1);

echo ternary (1.1);

?>

The above example will output:

100

80 T=C/2=INT(C/2)

In the original program the variable T is set to logical True or False based on the evaluation of a test for even/odd in C/2=INT(C/2). The evaluants are equal when C is an even number and rational so T is set to logical True. When C is odd or a decimal it evaluates to False and T is set to False.

The original program is approximately equivalent to:

IF C/2 = INT(C/2) THEN T=1 ELSE T=0

Probably the handling of the case of a negative value for C is dependant on the specific operating system.

In the example program we perform the same test by comparing $C in an evaluation with integer. If we simply compare $C we find is_int($C) is true for every rational number, by dividing by 2 as is_int($C/2) we find the test is only true in the case of all rational even numbers. In both the original program and the example program the output of the evaluation is logical True or False and the variable is assigned this value.

Additionally to the link in the comments the source code is viewable from this url and can be downloaded or executed.

2
  • 2
    This doesn’t explain it very well, to put it mildly. You didn’t explain how the PHP corresponds to the BASIC code (and it’s a somewhat ‘artistic’ translation anyway, since you substituted is_int for the equality test). And the demo link is rather silly, since it can’t be observed that this is the actual code that outputs this. You might as well have linked to data:text/plain,100. May 31, 2021 at 12:50
  • Working on other things for the presentation of this, will get back to add more colour to the post.
    – Willtech
    May 31, 2021 at 15:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .