@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
-@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006
-@c Free Software Foundation, Inc.
+@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2009,
+@c 2010, 2011, 2012 Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@node Pretty Printing
objects. This is especially useful for deeply nested or complex data
structures, such as lists and vectors.
-The module is loaded by simply saying.
+The module is loaded by entering the following:
@lisp
(use-modules (ice-9 pretty-print))
@end deffn
+@cindex truncated printing
+Also exported by the @code{(ice-9 pretty-print)} module is
+@code{truncated-print}, a procedure to print Scheme datums, truncating
+the output to a certain number of characters. This is useful when you
+need to present an arbitrary datum to the user, but you only have one
+line in which to do so.
+
+@lisp
+(define exp '(a b #(c d e) f . g))
+(truncated-print exp #:width 10) (newline)
+@print{} (a b . #)
+(truncated-print exp #:width 15) (newline)
+@print{} (a b # f . g)
+(truncated-print exp #:width 18) (newline)
+@print{} (a b #(c ...) . #)
+(truncated-print exp #:width 20) (newline)
+@print{} (a b #(c d e) f . g)
+(truncated-print "The quick brown fox" #:width 20) (newline)
+@print{} "The quick brown..."
+(truncated-print (current-module) #:width 20) (newline)
+@print{} #<directory (gui...>
+@end lisp
+
+@code{truncated-print} will not output a trailing newline. If an expression does
+not fit in the given width, it will be truncated -- possibly
+ellipsized@footnote{On Unicode-capable ports, the ellipsis is represented by
+character `HORIZONTAL ELLIPSIS' (U+2026), otherwise it is represented by three
+dots.}, or in the worst case, displayed as @nicode{#}.
+
+@deffn {Scheme Procedure} truncated-print obj [port] [keyword-options]
+Print @var{obj}, truncating the output, if necessary, to make it fit
+into @var{width} characters. By default, @var{obj} will be printed using
+@code{write}, though that behavior can be overridden via the
+@var{display?} keyword argument.
+
+The default behaviour is to print depth-first, meaning that the entire
+remaining width will be available to each sub-expression of @var{obj} --
+e.g., if @var{obj} is a vector, each member of @var{obj}. One can attempt to
+``ration'' the available width, trying to allocate it equally to each
+sub-expression, via the @var{breadth-first?} keyword argument.
+
+The further @var{keyword-options} are keywords and parameters as
+follows,
+
+@table @asis
+@item @nicode{#:display?} @var{flag}
+If @var{flag} is true then print using @code{display}. The default is
+@code{#f} which means use @code{write} style. (@pxref{Writing})
+
+@item @nicode{#:width} @var{columns}
+Print within the given @var{columns}. The default is 79.
+
+@item @nicode{#:breadth-first?} @var{flag}
+If @var{flag} is true, then allocate the available width breadth-first
+among elements of a compound data structure (list, vector, pair,
+etc.). The default is @code{#f} which means that any element is
+allowed to consume all of the available width.
+@end table
+@end deffn
+
+
@node Formatted Output
@section Formatted Output
@cindex formatted output
instead of @nicode{%}, and are more powerful.
@sp 1
-@deffn {Scheme Procedure} format dest fmt [args@dots{}]
+@deffn {Scheme Procedure} format dest fmt arg @dots{}
Write output specified by the @var{fmt} string to @var{dest}.
@var{dest} can be an output port, @code{#t} for
-@code{current-output-port} (@pxref{Default Ports}), a number for
-@code{current-error-port}, or @code{#f} to return the output as a
-string.
+@code{current-output-port} (@pxref{Default Ports}), or @code{#f} to
+return the output as a string.
@var{fmt} can contain literal text to be output, and @nicode{~}
escapes. Each escape has the form
@var{commawidth}.
Output an integer argument as a decimal, hexadecimal, octal or binary
-integer (respectively).
+integer (respectively), in a locale-independent way.
@example
(format #t "~d" 123) @print{} 123
@end example
@nicode{~:d} adds commas (or the @var{commachar} parameter) every
-three digits (or the @var{commawidth} parameter many).
+three digits (or the @var{commawidth} parameter many). However, when
+your intent is to write numbers in a way that follows typographical
+conventions, using @nicode{~h} is recommended.
@example
(format #t "~:d" 1234567) @print{} 1,234,567
printed instead of the value.
@example
-(format #t "~5,,,'xf" 12345) @print{} 12345
-(format #t "~4,,,'xf" 12345) @print{} xxxx
+(format #t "~6,,,'xf" 12345) @print{} 12345.
+(format #t "~5,,,'xf" 12345) @print{} xxxxx
+@end example
+
+@item @nicode{~h}
+Localized number@footnote{The @nicode{~h} format specifier first
+appeared in Guile version 2.0.6.}. Parameters: @var{width},
+@var{decimals}, @var{padchar}.
+
+Like @nicode{~f}, output an exact or floating point number, but do so
+according to the current locale, or according to the given locale object
+when the @code{:} modifier is used (@pxref{Number Input and Output,
+@code{number->locale-string}}).
+
+@example
+(format #t "~h" 12345.5678) ; with "C" as the current locale
+@print{} 12345.5678
+
+(format #t "~14,,'*:h" 12345.5678
+ (make-locale LC_ALL "en_US"))
+@print{} ***12,345.5678
+
+(format #t "~,2:h" 12345.5678
+ (make-locale LC_NUMERIC "fr_FR"))
+@print{} 12 345,56
@end example
@item @nicode{~e}
@c FIXME: MANTDIGITS with negative INTDIGITS doesn't match CL spec,
@c believe the spec says it ought to still show mantdigits+1 sig
-@c figures, ie. leading zeros don't count towards MANTDIGITS, but it
+@c figures, i.e. leading zeros don't count towards MANTDIGITS, but it
@c seems to just treat MANTDIGITS as how many digits after the
@c decimal point.
(@pxref{Internationalization}).
@item @nicode{~y}
-Pretty print. No parameters.
+Structured printing. Parameters: @var{width}.
+
+@nicode{~y} outputs an argument using @code{pretty-print}
+(@pxref{Pretty Printing}). The result will be formatted to fit within
+@var{width} columns (79 by default), consuming multiple lines if
+necessary.
-Output an argument with @code{pretty-print} (@pxref{Pretty Printing}).
+@nicode{~@@y} outputs an argument using @code{truncated-print}
+(@pxref{Pretty Printing}). The resulting code will be formatted to fit
+within @var{width} columns (79 by default), on a single line. The
+output will be truncated if necessary.
+
+@nicode{~:@@y} is like @nicode{~@@y}, except the @var{width} parameter
+is interpreted to be the maximum column to which to output. That is to
+say, if you are at column 10, and @nicode{~60:@@y} is seen, the datum
+will be truncated to 50 columns.
@item @nicode{~?}
@itemx @nicode{~k}
@section File Tree Walk
@cindex file tree walk
+@cindex file system traversal
+@cindex directory traversal
+
The functions in this section traverse a tree of files and
-directories, in a fashion similar to the C @code{ftw} and @code{nftw}
-routines (@pxref{Working with Directory Trees,,, libc, GNU C Library
-Reference Manual}).
+directories. They come in two flavors: the first one is a high-level
+functional interface, and the second one is similar to the C @code{ftw}
+and @code{nftw} routines (@pxref{Working with Directory Trees,,, libc,
+GNU C Library Reference Manual}).
@example
(use-modules (ice-9 ftw))
@end example
@sp 1
-@defun ftw startname proc ['hash-size n]
+@deffn {Scheme Procedure} file-system-tree file-name [enter? [stat]]
+Return a tree of the form @code{(@var{file-name} @var{stat}
+@var{children} ...)} where @var{stat} is the result of @code{(@var{stat}
+@var{file-name})} and @var{children} are similar structures for each
+file contained in @var{file-name} when it designates a directory.
+
+The optional @var{enter?} predicate is invoked as @code{(@var{enter?}
+@var{name} @var{stat})} and should return true to allow recursion into
+directory @var{name}; the default value is a procedure that always
+returns @code{#t}. When a directory does not match @var{enter?}, it
+nonetheless appears in the resulting tree, only with zero children.
+
+The @var{stat} argument is optional and defaults to @code{lstat}, as for
+@code{file-system-fold} (see below.)
+
+The example below shows how to obtain a hierarchical listing of the
+files under the @file{module/language} directory in the Guile source
+tree, discarding their @code{stat} info:
+
+@example
+(use-modules (ice-9 match))
+
+(define remove-stat
+ ;; Remove the `stat' object the `file-system-tree' provides
+ ;; for each file in the tree.
+ (match-lambda
+ ((name stat) ; flat file
+ name)
+ ((name stat children ...) ; directory
+ (list name (map remove-stat children)))))
+
+(let ((dir (string-append (assq-ref %guile-build-info 'top_srcdir)
+ "/module/language")))
+ (remove-stat (file-system-tree dir)))
+
+@result{}
+("language"
+ (("value" ("spec.go" "spec.scm"))
+ ("scheme"
+ ("spec.go"
+ "spec.scm"
+ "compile-tree-il.scm"
+ "decompile-tree-il.scm"
+ "decompile-tree-il.go"
+ "compile-tree-il.go"))
+ ("tree-il"
+ ("spec.go"
+ "fix-letrec.go"
+ "inline.go"
+ "fix-letrec.scm"
+ "compile-glil.go"
+ "spec.scm"
+ "optimize.scm"
+ "primitives.scm"
+ @dots{}))
+ @dots{}))
+@end example
+@end deffn
+
+@cindex file system combinator
+
+It is often desirable to process directories entries directly, rather
+than building up a tree of entries in memory, like
+@code{file-system-tree} does. The following procedure, a
+@dfn{combinator}, is designed to allow directory entries to be processed
+directly as a directory tree is traversed; in fact,
+@code{file-system-tree} is implemented in terms of it.
+
+@deffn {Scheme Procedure} file-system-fold enter? leaf down up skip error init file-name [stat]
+Traverse the directory at @var{file-name}, recursively, and return the
+result of the successive applications of the @var{leaf}, @var{down},
+@var{up}, and @var{skip} procedures as described below.
+
+Enter sub-directories only when @code{(@var{enter?} @var{path}
+@var{stat} @var{result})} returns true. When a sub-directory is
+entered, call @code{(@var{down} @var{path} @var{stat} @var{result})},
+where @var{path} is the path of the sub-directory and @var{stat} the
+result of @code{(false-if-exception (@var{stat} @var{path}))}; when it is
+left, call @code{(@var{up} @var{path} @var{stat} @var{result})}.
+
+For each file in a directory, call @code{(@var{leaf} @var{path}
+@var{stat} @var{result})}.
+
+When @var{enter?} returns @code{#f}, or when an unreadable directory is
+encountered, call @code{(@var{skip} @var{path} @var{stat}
+@var{result})}.
+
+When @var{file-name} names a flat file, @code{(@var{leaf} @var{path}
+@var{stat} @var{init})} is returned.
+
+When an @code{opendir} or @var{stat} call fails, call @code{(@var{error}
+@var{path} @var{stat} @var{errno} @var{result})}, with @var{errno} being
+the operating system error number that was raised---e.g.,
+@code{EACCES}---and @var{stat} either @code{#f} or the result of the
+@var{stat} call for that entry, when available.
+
+The special @file{.} and @file{..} entries are not passed to these
+procedures. The @var{path} argument to the procedures is a full file
+name---e.g., @code{"../foo/bar/gnu"}; if @var{file-name} is an absolute
+file name, then @var{path} is also an absolute file name. Files and
+directories, as identified by their device/inode number pair, are
+traversed only once.
+
+The optional @var{stat} argument defaults to @code{lstat}, which means
+that symbolic links are not followed; the @code{stat} procedure can be
+used instead when symbolic links are to be followed (@pxref{File System,
+stat}).
+
+The example below illustrates the use of @code{file-system-fold}:
+
+@example
+(define (total-file-size file-name)
+ "Return the size in bytes of the files under FILE-NAME (similar
+to `du --apparent-size' with GNU Coreutils.)"
+
+ (define (enter? name stat result)
+ ;; Skip version control directories.
+ (not (member (basename name) '(".git" ".svn" "CVS"))))
+ (define (leaf name stat result)
+ ;; Return RESULT plus the size of the file at NAME.
+ (+ result (stat:size stat)))
+
+ ;; Count zero bytes for directories.
+ (define (down name stat result) result)
+ (define (up name stat result) result)
+
+ ;; Likewise for skipped directories.
+ (define (skip name stat result) result)
+
+ ;; Ignore unreadable files/directories but warn the user.
+ (define (error name stat errno result)
+ (format (current-error-port) "warning: ~a: ~a~%"
+ name (strerror errno))
+ result)
+
+ (file-system-fold enter? leaf down up skip error
+ 0 ; initial counter is zero bytes
+ file-name))
+
+(total-file-size ".")
+@result{} 8217554
+
+(total-file-size "/dev/null")
+@result{} 0
+@end example
+@end deffn
+
+The alternative C-like functions are described below.
+
+@deffn {Scheme Procedure} scandir name [select? [entry<?]]
+Return the list of the names of files contained in directory @var{name}
+that match predicate @var{select?} (by default, all files). The
+returned list of file names is sorted according to @var{entry<?}, which
+defaults to @code{string-locale<?} such that file names are sorted in
+the locale's alphabetical order (@pxref{Text Collation}). Return
+@code{#f} when @var{name} is unreadable or is not a directory.
+
+This procedure is modeled after the C library function of the same name
+(@pxref{Scanning Directory Content,,, libc, GNU C Library Reference
+Manual}).
+@end deffn
+
+@deffn {Scheme Procedure} ftw startname proc ['hash-size n]
Walk the file system tree descending from @var{startname}, calling
@var{proc} for each file and directory.
In the current implementation, returning non-@code{#t} from @var{proc}
is the only valid way to terminate @code{ftw}. @var{proc} must not
use @code{throw} or similar to escape.
-@end defun
+@end deffn
-@defun nftw startname proc ['chdir] ['depth] ['hash-size n] ['mount] ['physical]
+@deffn {Scheme Procedure} nftw startname proc ['chdir] ['depth] ['hash-size n] ['mount] ['physical]
Walk the file system tree starting at @var{startname}, calling
@var{proc} for each file and directory. @code{nftw} has extra
features over the basic @code{ftw} described above.
completion, or otherwise the non-@code{#t} value from @var{proc} which
caused the stop.
-@c For reference, one reason not to esacpe is that the current
+@c For reference, one reason not to escape is that the current
@c directory is not saved and restored with dynamic-wind. Maybe
@c changing that would be enough to allow escaping.
@c
In the current implementation, returning non-@code{#t} from @var{proc}
is the only valid way to terminate @code{ftw}. @var{proc} must not
use @code{throw} or similar to escape.
-@end defun
+@end deffn
@node Queues
@section Streams
@cindex streams
+This section documents Guile's legacy stream module. For a more
+complete and portable stream library, @pxref{SRFI-41}.
+
A stream represents a sequence of values, each of which is calculated
only when required. This allows large or even infinite sequences to
be represented and manipulated with familiar operations like ``car'',
@end example
@sp 1
-@defun make-stream proc initial-state
+@deffn {Scheme Procedure} make-stream proc initial-state
Return a new stream, formed by calling @var{proc} successively.
Each call is @code{(@var{proc} @var{state})}, it should return a pair,
being the new @var{state} for the next call. For the first call
@var{state} is the given @var{initial-state}. At the end of the
stream, @var{proc} should return some non-pair object.
-@end defun
+@end deffn
-@defun stream-car stream
+@deffn {Scheme Procedure} stream-car stream
Return the first element from @var{stream}. @var{stream} must not be
empty.
-@end defun
+@end deffn
-@defun stream-cdr stream
+@deffn {Scheme Procedure} stream-cdr stream
Return a stream which is the second and subsequent elements of
@var{stream}. @var{stream} must not be empty.
-@end defun
+@end deffn
-@defun stream-null? stream
+@deffn {Scheme Procedure} stream-null? stream
Return true if @var{stream} is empty.
-@end defun
+@end deffn
-@defun list->stream list
-@defunx vector->stream vector
+@deffn {Scheme Procedure} list->stream list
+@deffnx {Scheme Procedure} vector->stream vector
Return a stream with the contents of @var{list} or @var{vector}.
@var{list} or @var{vector} should not be modified subsequently, since
it's unspecified whether changes there will be reflected in the stream
returned.
-@end defun
+@end deffn
-@defun port->stream port readproc
+@deffn {Scheme Procedure} port->stream port readproc
Return a stream which is the values obtained by reading from
@var{port} using @var{readproc}. Each read call is
@code{(@var{readproc} @var{port})}, and it should return an EOF object
@example
(port->stream (open-input-file "/foo/bar.txt") read-char)
@end example
-@end defun
+@end deffn
-@defun stream->list stream
+@deffn {Scheme Procedure} stream->list stream
Return a list which is the entire contents of @var{stream}.
-@end defun
+@end deffn
-@defun stream->reversed-list stream
+@deffn {Scheme Procedure} stream->reversed-list stream
Return a list which is the entire contents of @var{stream}, but in
reverse order.
-@end defun
+@end deffn
-@defun stream->list&length stream
+@deffn {Scheme Procedure} stream->list&length stream
Return two values (@pxref{Multiple Values}), being firstly a list
which is the entire contents of @var{stream}, and secondly the number
of elements in that list.
-@end defun
+@end deffn
-@defun stream->reversed-list&length stream
+@deffn {Scheme Procedure} stream->reversed-list&length stream
Return two values (@pxref{Multiple Values}) being firstly a list which
is the entire contents of @var{stream}, but in reverse order, and
secondly the number of elements in that list.
-@end defun
+@end deffn
-@defun stream->vector stream
+@deffn {Scheme Procedure} stream->vector stream
Return a vector which is the entire contents of @var{stream}.
-@end defun
+@end deffn
-@defun stream-fold proc init stream0 @dots{} streamN
+@defun stream-fold proc init stream1 stream2 @dots{}
Apply @var{proc} successively over the elements of the given streams,
from first to last until the end of the shortest stream is reached.
Return the result from the last @var{proc} call.
-Each call is @code{(@var{proc} elem0 @dots{} elemN prev)}, where each
+Each call is @code{(@var{proc} elem1 elem2 @dots{} prev)}, where each
@var{elem} is from the corresponding @var{stream}. @var{prev} is the
return from the previous @var{proc} call, or the given @var{init} for
the first call.
@end defun
-@defun stream-for-each proc stream0 @dots{} streamN
+@defun stream-for-each proc stream1 stream2 @dots{}
Call @var{proc} on the elements from the given @var{stream}s. The
return value is unspecified.
-Each call is @code{(@var{proc} elem0 @dots{} elemN)}, where each
+Each call is @code{(@var{proc} elem1 elem2 @dots{})}, where each
@var{elem} is from the corresponding @var{stream}.
@code{stream-for-each} stops when it reaches the end of the shortest
@var{stream}.
@end defun
-@defun stream-map proc stream0 @dots{} streamN
+@defun stream-map proc stream1 stream2 @dots{}
Return a new stream which is the results of applying @var{proc} to the
elements of the given @var{stream}s.
-Each call is @code{(@var{proc} elem0 @dots{} elemN)}, where each
+Each call is @code{(@var{proc} elem1 elem2 @dots{})}, where each
@var{elem} is from the corresponding @var{stream}. The new stream
ends when the end of the shortest given @var{stream} is reached.
@end defun
of further input for an application level logical expression is
maintained too, and passed through to the reader.
-@defun make-buffered-input-port reader
+@deffn {Scheme Procedure} make-buffered-input-port reader
Create an input port which returns characters obtained from the given
@var{reader} function. @var{reader} is called (@var{reader} cont),
and should return a string or an EOF object.
@code{set-buffered-input-continuation?!} below. If the user has
entered a partial expression then it allows @var{reader} for instance
to give a different prompt to show more is required.
-@end defun
+@end deffn
-@defun make-line-buffered-input-port reader
+@deffn {Scheme Procedure} make-line-buffered-input-port reader
@cindex Line buffered input
Create an input port which returns characters obtained from the
specified @var{reader} function, similar to
@var{reader} is called (@var{reader} cont), and should return a string
or an EOF object as above. Each string is a line of input without a
newline character, the port code inserts a newline after each string.
-@end defun
+@end deffn
-@defun set-buffered-input-continuation?! port cont
+@deffn {Scheme Procedure} set-buffered-input-continuation?! port cont
Set the input continuation flag for a given buffered input
@var{port}.
(let ((obj (read my-port)))
...
@end example
-@end defun
+@end deffn
@c Local Variables: