reading lists, matrices, and arrays



I wrote some code for reading lists, matrices, and arrays from a file.
Here's a demonstration with some questions along the way.

(C1) load("l:/maxima-io/io.lisp")$
(C2) fn : "l:/maxima-io/fp.data";
(D2)                                 l:/maxima-io/fp.data

The function read_list reads all objects in a file and places them in a
Maxima list.  Objects must be separated with whitespace; linefeeds are 
ignored.  My file fp.data is

0 1 2 
3 4 5
6 7 8

The numbers could be floats.

(C3) read_list(fn);
(D3)                             [0, 1, 2, 3, 4, 5, 6, 7, 8]


read_list doesn't close the file--reading from fn again gives an empty
list 
(C4) read_list(fn);
(D4)                                          []

Question 1:  Is this behavior what folks would like?  Or should the file 
be closed after reading? 

We can reset the file position to the start using

(C5) reset_file_position(fn)$
(C6) read_list(fn);
(D6)                             [0, 1, 2, 3, 4, 5, 6, 7, 8]
(C7) reset_file_position(fn)$

To read objects starting with the first and continue reading until either 
5 have been read or we run out of data, use the optional arguments

(C8) read_list(fn,1,5);
(D8)                                   [0, 1, 2, 3, 4]
(C9) read_list(fn,1,5);
(D9)                                     [5, 6, 7, 8]
(C10) read_list(fn,1,5);
(D10)                                         []
(C11) reset_file_position(fn)$

With one argument, read_matrix forms a matrix from each line of the file.
My file fn has three lines; thus

(C12) read_matrix(fn);
                                         [ 0  1  2 ]
                                         [         ]
(D12)                                    [ 3  4  5 ]
                                         [         ]
                                         [ 6  7  8 ]

(C13) reset_file_position(fn)$

To read the first 2 lines, use an optional first argument

(C14) read_matrix(fn,2);
                                         [ 0  1  2 ]
(D14)                                    [         ]
                                         [ 3  4  5 ]
(C15) reset_file_position(fn)$

With two optional arguments, ignore line feeds and read the objects into 
the matrix linearly

(C16) read_matrix(fn,2,2);
                                           [ 0  1 ]
(D16)                                      [      ]
                                           [ 2  3 ]
(C17) reset_file_position(fn)$

Finally, we can read data into an array.

(C18) array(a,2,2)$
(C19) read_array(fn,a);
(D19)                                         a
(C20) listarray(a);
(D20)                            [0, 1, 2, 3, 4, 5, 6, 7, 8]

If there isn't enough data left, we get an error

(C21) read_array(fn,a);
Not enough data left in "l:/maxima-io/fp.data" to fill the array. File 
position was not changed
 -- an error.  Quitting.  To debug this try DEBUGMODE(TRUE);)

To list all open files and closed files, use

(C22) list_open_files();
(D22)                               [l:/maxima-io/fp.data]
(C23) close_all_files();
Closing file l:/maxima-io/fp.data
(D23)                                       FALSE
(C24) 

(Open files are stored in a hash table; closing them removes them
from the hash table and closes the file).

Question 2:  Should these functions check that all objects are numbers? If
so what should happen to the file position when we read a non-number? 
Currently, a data file can contain anything that lisp:read can read.

Question 3: Should read_matrix check that all its rows are the same 
length? Currently, it's up to matrix, not read_matrix, to signal the 
error.  If read_matrix signals the error, what should happen to the
file position? 

io.lisp is about 156 lines long; I'll send it to anybody with an
interest in developing a non-experimental version.  I'll 
appreciate all comments. 

Barton