used for the entirely unrelated task of allowing variables to be used in DIM statements. Because strings in CP-V did not present themselves publicly as arrays of characters, the slicing syntax was not based on array syntax. This meant CP-V also allowed the construction of arrays of strings, something dialects like HP and Atari lacked because they used array notation for slicing. One could thus make a matrix of strings using DIM: 10 DIM A$(5,10) would define a matrix containing a total of 50 72-character strings in a 5 by 10 matrix. Because the system supported arrays, slicing syntax was somewhat more complex than the system found in other versions. Examples include: A$(1) selects the first string in an array of strings, while: A$(1,5) selects a string from location 1,5 in a 2D array (matrix). Slicing was handled by adding a colon within the parens: A$(:4) returned everything from the 4th character on: A$(:4,5) selects five characters starting with the 4th character, while: A$(1,5:4,5) selects five characters starting with the 4th character of the string in locations 1,5 in a 2D array. String constants could be delimited with either single or double quotes, making it easier to enclose quotes within lines. Valid examples include: PRINT 'THIS IS A STRING LITERAL' PRINT "THIS IS ANOTHER ONE" PRINT 'AND THIS IS "A THIRD"' PRINT "AND 'A FOURTH'" CP-V also includes the CHANGE command from Dartmouth BASIC, which converts a string into a series of EBCDIC numeric values and places them into a numeric array: 10 DIM B(6) 20 CHANGE "ABCDEF" TO B B will now contain a series of numbers corresponding to the EBCDIC values for each character. Input/Output SDS included a robust system for input/output based on "stream" numbers that could be specified in PRINT and INPUT statements. For instance, data could be read from a file using: 10 OPEN 'FILE1' TO :1,INPUT 20 INPUT :1,A The first line opens a disk file with the name "FILE1", assigns it to stream 1, and indicates it will be used for input. The second line reads the next data from stream 1, in this case the first value, and assigns the resulting data to variable A. The system also included a unique "key" system that allowed data to be numbered and then accessed randomly. This was accomplished by adding the key number after a semicolon: INPUT :1;9999,A will attempt to read record 9999.