> I can't seem to find a way to seek in and get the position in files
> using Gambit (4beta11). Wouldn't this be a handy feature?
Yes, I have been planing this for a while and have just completed the
implementation and documentation. Here it is:
@deffn procedure input-port-byte-position @var{port} @r{[}@var{position} @r{[}@var{whence}@r{]}@r{]}
@deffnx procedure output-port-byte-position @var{port} @r{[}@var{position} @r{[}@var{whence}@r{]}@r{]}
When called with a single argument these procedures return the byte
position where the next I/O operation would take place in the file
attached to the given @var{port} (relative to the beginning of the
file). When called with two or three arguments, the byte position for
subsequent I/O operations on the given @var{port} is changed to
@var{position}, which must be an exact integer. When @var{whence} is
omitted or is 0, the @var{position} is relative to the beginning of
the file. When @var{whence} is 1, the @var{position} is relative to
the current byte position of the file. When @var{whence} is 2, the
@var{position} is relative to the end of the file. The return value
is the new byte position. On most operating systems the byte position
for reading and writing of a given bidirectional port are the same.
When @code{input-port-byte-position} is called to change the byte
position of an input-port, all input buffers will be flushed so that
the next byte read will be the one at the given position.
When @code{output-port-byte-position} is called to change the byte
position of an output-port, there is an implicit call to
@code{force-output} before the position is changed.
For example:
@smallexample
> @b{(define p @r{@i{; p is an input-output-port}}
(open-file '(path: "test" char-encoding: latin1 create: maybe)))}
> @b{(list (input-port-byte-position p) (output-port-byte-position p))}
(0 0)
> @b{(display "abcdefghij\n" p)}
> @b{(list (input-port-byte-position p) (output-port-byte-position p))}
(0 0)
> @b{(force-output p)}
> @b{(list (input-port-byte-position p) (output-port-byte-position p))}
(11 11)
> @b{(input-port-byte-position p 2)}
2
> @b{(list (input-port-byte-position p) (output-port-byte-position p))}
(2 2)
> @b{(peek-char p)}
#\c
> @b{(list (input-port-byte-position p) (output-port-byte-position p))}
(11 11)
> @b{(output-port-byte-position p -7 2)}
4
> @b{(list (input-port-byte-position p) (output-port-byte-position p))}
(4 4)
> @b{(write-char #\! p)}
> @b{(list (input-port-byte-position p) (output-port-byte-position p))}
(4 4)
> @b{(force-output p)}
> @b{(list (input-port-byte-position p) (output-port-byte-position p))}
(5 5)
> @b{(input-port-byte-position p 1)}
1
> @b{(read p)}
bcd!fghij
@end smallexample
@end deffn
> Also, while I'm making suggestions: Have you thought about
> implementing a simple package system, for example something like
> Chicken Scheme's eggs[3]?
No. I'm not saying this wouldn't be useful, just that I haven't
perceived a need for it yet. There's really nothing to change in
Gambit itself to implement a package system like the one Chicken uses
because Gambit's installation directory (/usr/local/Gambit-C) can be
used for this. The subdirectory /usr/local/Gambit-C/package would
store the installed packages, and the programs would use these
packages like this:
(include "~~/package/Xlib.scm")
(include "~~/package/arrays.scm")
...
or
(load "~~/package/foo")
The system extension file (~~/gambcext) could also be modified for the
packages that need to permanently extend Gambit (this file is loaded
whenever the interpreter is started).
The most tedious in all of this is to implement the package management
tool that installs the packages, compiles them if needed, checks for
the latest version, checks package dependencies, etc. If you want to
contribute such a tool please be my guest. What I can do is help you
out in the design and host the packages that people contribute on
Gambit's web site.
Of course some of this work may have to be duplicated when the R6RS
module system comes out...
Marc