Introduction

From Maze

(Difference between revisions)
Jump to: navigation, search
(→One Line)
(→10 PRINT CHR$(205.5+RND(1)); : GOTO 10)
Line 29:Line 29:
= 10 PRINT CHR$(205.5+RND(1)); : GOTO 10 =
= 10 PRINT CHR$(205.5+RND(1)); : GOTO 10 =
−
By way of introducing this program, here is an initial explication of what each of its tokens do and mean.
+
By way of introducing this program, here is an initial explication of what each part of it does and means.
== 10 ==
== 10 ==
−
"10" is the only line number in this one-line program, and probably the most conventional line number to use for the first line of any BASIC program. Most of the programs in the ''Commodore 64 User's Guide'' start with line 10, a choice typical on other platforms as well. Numbering lines in increments of 10, rather than simply as 1, 2, 3, ..., allows for lines to be inserted more easily if the need arises during program development: the lines after the insertion point will not have to be renumbered.
+
"10" is the only line number in this one-line program, and is probably the most conventional line number to use for the first line of any BASIC program. Most of the programs in the ''Commodore 64 User's Guide'' start with line 10, a choice which was typical in other books and on other platforms as well. Numbering lines in increments of 10, rather than simply as 1, 2, 3, ..., allows for lines to be inserted more easily if the need arises during program development: the lines after the insertion point will not have to be renumbered.
−
The standard version of BASIC for the Commodore 64, BASIC version 2, made this sort of line numbering practice wise. There were some extensions to BASIC which provided a RENUMBER or RENUM command that would automatically redo the line numbering. This convenience had a downside: if the line numbers were spaced out in a meaningful way so that part of the work was done beginning at 100, another segment beginning at 200, and so on, that segmentation would be obliterated by the renumbering.
+
The standard version of BASIC for the Commodore 64, BASIC version 2 by Microsoft, made this sort of line numbering practice wise. There were some extensions to this BASIC which later provided a RENUMBER or RENUM command that would automatically redo the line numbering to 10, 20, 30, etc. This convenience had a downside: if the line numbers were spaced out in a meaningful way so that part of the work was done beginning at 100, another segment beginning at 200, and so on, that thoughtful segmentation would be obliterated. In any case, the RENUMBER was not provided with the version of BASIC that shipped on the Commodore 64.
−
The variant of this program that appears in ''RUN'' uses 8 as its line number. This makes the program more concise in its textual representation, although it does not save any memory -- for each line of BASIC stored in RAM, two bytes are allocated for the line number, whether it is 1 or 63999 (the maximum value allowed). Of course, any single digit, including "1," could have been used instead. But for a program that loops forever, it is perhaps also appealing to have the one line numbered "8," an infinity sign turned on its side, a digit that suggests the potentially endless loop of the figure eight. Although "8" may offer us grist for interpretation, it is a departure from tradition and from standard line-numbering convention for a multi-line program. Mainly, the ''RUN'' program simply attests to the arbitrariness of the line number.
+
The variant of this program that appears in ''RUN'' uses 8 as its line number. This makes the program more concise in its textual representation, although it does not save any memory -- for each line of BASIC stored in RAM, two bytes are allocated for the line number, whether it is 1 or 63999 (the maximum value allowed). Of course, any single digit, including "1," could have been used instead. But for a program that loops forever, it is perhaps also appealing to have the one line numbered "8," an infinity sign turned on its side, a digit that suggests the potentially endless loop of the figure eight. Although "8" may offer us grist for interpretation, it is a departure from tradition and from standard line-numbering convention for a multi-line program. Mainly, the ''RUN'' program simply attests to the arbitrariness of the line number and that starting with 10 was a convention but was not required.
−
Why are line numbers needed at all in a BASIC program? The programs we write today in C, Perl, Python, Ruby, and other languages don't use line numbers. They aren't necessary in BASIC, as demonstrated by versions of BASIC including QBASIC and Visual Basic. If one wants the program to branch to a particular statement, a label can be attached to that statement. Where line numbers particularly help is in editing the program, particularly when using a line editor or without access to a scrolling full-screen editor. The Commodore 64 does allow limited screen editing in the standard BASIC interpreter: the arrow keys can be used to move the cursor to a line, the line can be edited, and pressing return saves the new version of the line. This is a better editing capability than comes standard on the Apple II, but there is still no scrollback in BASIC on the C64. Line numbers provide a convenient way to list a particular line or range of lines. Typing a line number by itself will delete that line, if one exists in memory. The interactive editing abilities that line numbers allow were well-represented even in early versions of BASIC, including the first version of the BASIC that worked with the Dartmouth Time Sharing System.
+
Why are line numbers needed at all in a BASIC program? The programs written today in C, Perl, Python, Ruby, and other languages don't use line numbers, which actually aren't necessary in BASIC, as demonstrated by versions of BASIC including QBASIC and Visual Basic. If one wants the program to branch to a particular statement, a label can be attached instead of a line number. Where line numbers particularly help is in editing the program, particularly when using a line editor or without access to a scrolling full-screen editor. The Commodore 64 does allow limited screen editing when programming in BASIC: the arrow keys can be used to move the cursor to a line, the line can be edited, and pressing return saves the new version of the line. This is a better editing capability than comes standard on the Apple II, but there is still no scrollback (no ability to go back past the current beginning of the screen) in BASIC on the C64. Line numbers provide a convenient way to get back to an earlier part of the program and to list a particular line or range of lines. Typing a line number by itself will delete the corresponding line, if one exists in memory. The interactive editing abilities that line numbers allow were well-represented even in early versions of BASIC, including the first version of the BASIC that worked with the Dartmouth Time Sharing System.
−
== (SPACE) ==
+
== {SPACE} ==
−
The space between "10" and "PRINT" is optional, as are all of the spaces in this program. If a user enters "10PRINTCHR$(205.5+RND(1));:GOTO10" that line will function identically. The spaces are of course helpful to the person trying to type in this line of code correctly: they make it more legible and more understandable.
+
The space between "10" and "PRINT" is actually optional, as are all of the spaces in this program. If the line "10PRINTCHR$(205.5+RND(1));:GOTO10" is typed in instead, that program will function exactly as this one does. The spaces are of course helpful to the person trying to type in this line of code correctly: they make it more legible and more understandable.
−
Even in this exceedingly short program, which has no variables (and thus no variable names) and no comments, the presence of these optional spaces indicates some concern for the people who will deal with this code. Spaces acknowledge that the code is not only something to be automatically translated to machine instructions, but is also something to be read, understood, and potentially modified and built upon by human programmers. The same acknowledgment is seen in the way the keywords are presented in their canonical form: "?" could be used instead of PRINT there are two-character abbreviations that allow the other keywords to be entered quickly. But, for clarity, the longer but easier-to-read version of these keywords is shown.
+
Even in this exceedingly short program, which has no variables (and thus no variable names) and no comments, the presence of these optional spaces indicates some concern for the people who will deal with this code. Spaces acknowledge that the code is not only something to be automatically translated to machine instructions, but is also something to be read, understood, and potentially modified and built upon by human programmers. The same acknowledgment is seen in the way the keywords are presented in their canonical form: "?" could be used instead of PRINT, and there are two-character abbreviations that allow the other keywords to be entered quickly. But, for clarity, the longer but easier-to-read version of these keywords is shown in this version of the program, as it is in printed variants.
== PRINT ==
== PRINT ==
−
This statement causes its argument to be displayed on the screen. The argument to PRINT can take a variety of forms, but here it is a string, like "HELLO WORLD" but generated by a function and only a single character long. This command is so well-known to us today that we may overlook that, as it is used here, it does not literally "print" anything. To send output to a printer, PRINT has to be followed by "#" and the appropriate device number, then a comma, and then the argument that is to be printed. By default, without a device number, the output goes to the screen - a television or composite video monitor.
+
This statement causes its argument to be displayed on the screen. The argument to PRINT can take a variety of forms, but here it is a string that is in many ways like the famous "HELLO WORLD." The string in this case is generated by a function and is only a single character long.
−
However, when BASIC was first developed in 1964 at Dartmouth College, the physical interface was different. Remarkably, the language was designed for college students to use in interactive sessions; they would not have to submit batch jobs on punch cards as was common at the time. However, users worked not at screens but at print terminals, initially Teletypes. So a PRINT command that executed successfully did actually cause something to be printed. Although BASIC was less than 20 years old when a version of it was made for the Commodore 64, that version nevertheless has a residue of history, leftover terms from before a change in the standard output technology. Although video displays replaced scrolls of paper with printed output, the keyword PRINT remained.
+
This command is so well-known to us today that we may overlook that, as it is used here, it does not literally "print" anything in the way we normally use the word. To send output to a printer, PRINT has to be followed by "#" and the appropriate device number, then a comma, and then the argument that is to be printed. By default, without a device number, the output goes to the screen -- in the case of the Commodore 64, a television or composite video monitor.
 +
 +
However, when BASIC was first developed in 1964 at Dartmouth College, the physical interface was different. Remarkably, the language was designed for college students to use in interactive sessions, so that they would not have to submit batch jobs on punch cards as was common at the time. However, the users and programmers at Dartmouth worked not at screens but at print terminals, initially Teletypes. So a PRINT command that executed successfully did actually cause something to be printed. Although BASIC was less than 20 years old when a version of it was made for the Commodore 64, that version nevertheless has a residue of history, leftover terms from before a change in the standard output technology. Although video displays replaced scrolls of paper with printed output, the keyword PRINT remained.
 +
 +
[The following paragraph should be moved into an appropriate chapter. -NM]
The automatic scrolling behavior that PRINT accomplishes (shifting the text up when at the bottom of the screen by calling the KERNAL's CHROUT routine) points back to the print heritage of home computing. While the video display is 40 characters wide, the Commodore 64 maintains an 80-column line internally, which is why BASIC lines can be at most 80 characters. This 80-column logical line hearkens back to the 80-column line of the print terminal - which itself derives from the 80 columns on punched cards, which had been in use for decades before general-purpose computing.
The automatic scrolling behavior that PRINT accomplishes (shifting the text up when at the bottom of the screen by calling the KERNAL's CHROUT routine) points back to the print heritage of home computing. While the video display is 40 characters wide, the Commodore 64 maintains an 80-column line internally, which is why BASIC lines can be at most 80 characters. This 80-column logical line hearkens back to the 80-column line of the print terminal - which itself derives from the 80 columns on punched cards, which had been in use for decades before general-purpose computing.
Line 57:Line 61:
== CHR$ ==
== CHR$ ==
−
This function takes a numeric code and returns the corresponding character, which may be a digit, a letter, a punctuation mark, a space, or a "character graphic," a non-typographical tile typically displayed alongside others to create an image. The standard numerical representation of characters in the 1980s, still is wide use today, is ASCII, a 7-bit code that represents 128 characters. On the Commodore 64 and previous Commodore computers, this representation was extended, as it often was in different ways on different systems. In extensions to ASCII, the other 128 numbers that can be represented in 8 bits are used for character graphics and other symbols. The Commodore 64's character set, which had been used previously on the Commodore PET, was nicknamed PETSCII.
+
This function takes a numeric code and returns the corresponding character, which may be a digit, a letter, a punctuation mark, a space, or a "character graphic," a non-typographical tile typically displayed alongside others to create an image. The standard numerical representation of characters in the 1980s, still in wide use today, is ASCII, a 7-bit code that represents 128 characters. On the Commodore 64 and previous Commodore computers, this representation was extended, as it often was in different ways on different systems. In extensions to ASCII, the other 128 numbers that can be represented in 8 bits are used for character graphics and other symbols. The Commodore 64's character set, which had been used previously on the Commodore PET, was nicknamed PETSCII.
The complement to CHR$ is the function ASC, which takes a quoted character and returns the corresponding numeric value. A user who is curious about the numeric value of a particular character, such as the capital letter A, can type PRINT ASC("A") and see the result, 65. A program can also use ASC to convert a character to a numeric representation, perform arithmetic on the number that results, and then convert the new number back to a character using CHR$. In lowercase mode, this can be used to shift character between uppercase and lowercase. Or this sort of manipulation might be used to implement a substitution cipher, for instance.
The complement to CHR$ is the function ASC, which takes a quoted character and returns the corresponding numeric value. A user who is curious about the numeric value of a particular character, such as the capital letter A, can type PRINT ASC("A") and see the result, 65. A program can also use ASC to convert a character to a numeric representation, perform arithmetic on the number that results, and then convert the new number back to a character using CHR$. In lowercase mode, this can be used to shift character between uppercase and lowercase. Or this sort of manipulation might be used to implement a substitution cipher, for instance.
−
Character graphics exist as special tiles that are more graphical than typographical. That is, they are mainly intended to be assembled into larger graphical images rather than typeset along letters, digits, and punctuation. But these tiles are placed in a typographical framework: A textual system, built on top of a bitmapped graphic display, is being reused for graphical purposes. This is a typical way in which a system, adapted for a new, particular purpose, is retrofitted to do something else.
+
Character graphics exist as special tiles that are more graphical than typographical. That is, they are mainly intended to be assembled into larger graphical images rather than "typeset" or placed along letters, digits, and punctuation. But these special tiles do exist in a typographical framework: A textual system, built on top of a bitmapped graphic display, is being reused for graphical purposes. This type of abstraction may not be a smooth, clean way of accomplishing new capabilities, but it represents a rather typical way in which a system, adapted for a new, particular purpose, can be retrofitted to do something else.
== ( ==
== ( ==
−
CHR$ and RND are both functions, so the keyword is followed in both cases by an argument in parentheses. CHR$ is a string function (it takes a numeric argument and returns a string) while RND is an arithmetic function (it takes a numeric argument and returns a number). The parentheses make it clear that, for instance, "RND(1-2)" is the same as "RND(-1)," while "RND(1)-2" is two subtracted from the result of "RND(1)".
+
CHR$ and RND are both functions, so the keyword is followed in both cases by an argument in parentheses. CHR$ ends with the dollar sign to indicate that it is a string function (it takes a numeric argument and returns a string) while RND does not, since it is an arithmetic function (it takes a numeric argument and returns a number). The parentheses here also make clear the order of arithmetic operations. For instance, "RND(1-2)" is the same as "RND(-1)," while "RND(1)-2" is two subtracted from the whatver value is returned by "RND(1)".
== 205.5 ==
== 205.5 ==
−
When converted into an integer, this value is truncated (rounded down) and becomes 205; if more than .5 and less than 1 is added to it, the integer result will be 206. This means the character printed will either be the one corresponding to 205 or the one corresponding to 206: A left-leaning or right-leaning diagonal line. A quirk of the Commodore 64 character set is that these two characters, and a run of several character graphics, have two numeric representations. Characters 109 and 110 duplicate 205 and 206, meaning that a program that has 109.5 instead of 205.5 will produce identical output.
+
All math in Commodore BASIC is done on floating point numbers, number with decimal places. When an integer results is needed (as it is in the case of CHR$), the conversion is done by BASIC automatically. If this value, 205.5, were to be converted into an integer directly, it would be truncated (rounded down) and would becomes 205. If more than .5 and less than 1 is added to 205.5, the integer result will be 206.
 +
 +
This means the character printed will either be the one corresponding to 205 or the one corresponding to 206: A left-leaning or right-leaning diagonal line. A quirk of the Commodore 64 character set is that these two characters, and a run of several character graphics, have two numeric representations. Characters 109 and 110 duplicate 205 and 206, meaning that 109.5 could replace 205.5 in this program and the identical output would be produced.
== + ==
== + ==
−
"+" here indicates addition, of course, but it's less obvious that this is the addition of two floating point numbers with a floating point result. The first of these is 205.5; the second is whatever value that RND returns, a value guaranteed to be between 0 and 1. There is no way to do integer addition in Commodore 64 BASIC: "+" ''always'' means floating-point addition. If an integer is provided as an argument, it is converted to a floating point number before the addition is done. The result is floating point number, although such a result is displayed without a decimal point or any digits to the right if those are all zero. This means that figuring out "2 + 2" is a much slower computation that it needs to be, but it also means that an easy-to-apply, one-size-fits all mathematical operation is provided for the programmer by BASIC. Whether the programmer wishes to add temperatures, prices, tomato soup cans, or anything else, "+" will work.
+
"+" here indicates addition, of course, but it's less obvious that this is the addition of two floating point numbers with a floating point result -- that is simply how Commodore 64 BASIC always works. The first number to be added is 205.5; the second is whatever value that RND returns, a value guaranteed to be between 0 and 1.
−
The origin of this mathematical symbol is, like "&," as an abbreviation for "and." As is still conventional on today's computers, the Commodore 64 has a special "plus" or addition key but does not have any way to type a multiplication sign or a division sign. While they appear in some 8-bit codes that extend ASCII and in Unicode, the multiplication and division signs are absent from ASCII and from PETSCII. Instead, the asterisk (*) and the slash, virgule, or solidus (/), are used. Given the computer's development as a machine for the manipulation of numbers, it is curious that typographical symbols have to be borrowed from their textual uses ("*" indicating a footnote, "/" a line break or a juxtaposition of terms) and pressed into service as mathematical symbols. Perhaps it can lead us to question the idea that the computer is essentially numeric rather than as textual or as graphical a device as it is a numerical one.
+
Because all arithmetic is done in floating point, figuring out "2 + 2" is a much slower computation that it needs to be. On the other hand, the universal use of floating-point math means that an easy-to-apply, one-size-fits all mathematical operation is provided for the programmer by BASIC. Whether the programmer wishes to add temperatures, prices, tomato soup cans, or anything else, "+" will work.
 +
 +
The origin of this mathematical symbol is, like "&," as an abbreviation for "and." As is still conventional on today's computers, the Commodore 64 has a special "plus" or addition key but does not have any way to type a multiplication sign or a division sign. While they appear in some 8-bit codes that extend ASCII and in Unicode, the multiplication and division signs are absent from ASCII and from PETSCII. Instead, the asterisk (*) and the slash, virgule, or solidus (/), are used. Given the computer's development as a machine for the manipulation of numbers, it is curious that typographical symbols have to be borrowed from their textual uses ("*" indicating a footnote, "/" a line break or a juxtaposition of terms) and pressed into service as mathematical symbols. But this has to do with the history of computer input devices, which in early days included teletypewriters, devices that were not originally made for mathematical communication.
== RND ==
== RND ==
−
To a first approximation, this function returns a random number, one which is between 0 and 1. The number returned is, more precisely, pseudorandom: while the sequence of numbers generated has no discernible pattern and is hard to predict, it is actually the same sequence each time. This is not a failing; the consistent output allows for debugging. More can be said about randomness, and much more is in chapter [???]. It is convenient that the number is always between 0 and 1; this allows it to easily be multiplied by another value and scaled to a different range. If one wishes to pick between two options at random, however, one can also test the random value to see if it is greater than .5. Or, as is done in this program, one can add 205.5 and convert to an integer so that 205 is produced with probability .5 and 206 with probability .5.
+
To a first approximation, this function returns a random number, one which is between 0 and 1. The number returned is, more precisely, pseudorandom. While the sequence of numbers generated has no easily discernible pattern and is hard for a person to predict, it is actually the same sequence each time. This is not entirely a failing; the consistent nature of this "random" output allows other programs to be tested time and time again by a programmer and for their output to be compared for consistency.
 +
 +
It is convenient that the number is always between 0 and 1; this allows it to easily be multiplied by another value and scaled to a different range. If one wishes to pick between two options at random, however, one can also simply test the random value to see if it is greater than .5. Or, as is done in this program, one can add 205.5 and convert to an integer so that 205 is produced with probability .5 and 206 with probability .5.
 +
 +
More can be said about randomness, and much more is said in the chapter on the topic.
== 1 ==
== 1 ==
−
When RND is given any positive value as an argument, it produces a number using the current seed. This means that when RND(1) is invoked immediately after startup, or before any other invocation of RND, it will always produce the same result: .185564016. The next invocation will also be the same, no matter what the time or which Commodore 64 is used, and the next. Since the sequence is deterministic, the pattern produced by the 10 PRINT ... program, when run before any other invocation of RND, is always the same.
+
When RND is given any positive value (such as this "1") as an argument, it produces a number using the current seed. This means that when RND(1) is invoked immediately after startup, or before any other invocation of RND, it will always produce the same result: .185564016. The next invocation will also be the same, no matter which Commodore 64 is used or at what time, and the next will be the same, too. Since the sequence is deterministic, the pattern produced by the 10 PRINT ... program, when run before any other invocation of RND, is a complex-looking on that is always the same.
== ; ==
== ; ==
Line 89:Line 101:
Using a semicolon after a string in a PRINT statement causes the next string to be printed immediately after the previous one, without a newline or any spaces between them. The other options are the use of a comma, which moves to the next tab stop (10 spaces), or the use of no symbol at all, which causes a newline to be printed.
Using a semicolon after a string in a PRINT statement causes the next string to be printed immediately after the previous one, without a newline or any spaces between them. The other options are the use of a comma, which moves to the next tab stop (10 spaces), or the use of no symbol at all, which causes a newline to be printed.
−
Although this use of the semicolon from PRINT formatting was not original to BASIC, the semicolon was introduced very early on at Dartmouth, in version 2, a minor update that had only one other change.
+
Although this use of the semicolon from PRINT formatting was not original to BASIC, the semicolon was introduced very early on at Dartmouth, in version 2, a minor update that had only one other change. The semicolon here is enough to show that not only short computer programs like this one, but also the languages in which they are written, change over time.
== : ==
== : ==
−
The colon separates two BASIC statements which could have been placed on different lines. In a program like this on the original Dartmouth version of BASIC, they would have to each be on their own line. To keep programs clear and uncluttered, there could be no multi-statement lines. The colon was introduced by Microsoft, the leading developer of microcomputer BASIC interpreters, to allow more code to be packed onto home computers.
+
The colon separates two BASIC statements which could have been placed on different lines. In a program like this on the original Dartmouth version of BASIC, each statement would have to be on its own line, since, to keep programs clear and uncluttered, only a single statement per line was allowed. The colon was introduced by Microsoft, the leading developer of microcomputer BASIC interpreters, as one of several moves to allow more code to be packed onto home computers.
== GOTO ==
== GOTO ==
−
This is an unconditional branch to the line indicated - which is the program's only line, line 10. The GOTO keyword and line number functions like the JMP machine language instruction. In this case, it returns control to an earlier point, causing the first statement to be executed endlessly - or at least until the program is somehow interrupted, either by the user pressing the STOP key or by the power being shut off.
+
This is an unconditional branch to the line indicated -- the program's only line, line 10. The GOTO keyword and line number functions like the JMP machine language instruction. In this case, it returns control to an earlier point, causing the first statement to be executed endlessly -- or at least until the program is somehow interrupted, either by the user pressing the STOP key or by the power being shut off.
 +
 +
GOTO, although not original to BASIC, came to be very strongly associated with BASIC. A denunciation of GOTO is possibly the most-discussed document in the history of programming languages; it plays an important part in the move from unstructured high-level languages (such as BASIC) to structured languages such as ALGOL, Pascal, Ada, and today's object-oriented programming languages, which incorporate the control structures and principles of these languages.
= Plan of the Book =
= Plan of the Book =

Revision as of 16:28, 31 July 2011

View this revision of Introduction.

Personal tools