Gwydion Dylan Library Reference Guide

Edited by

Peter Housel

Andreas Bogk

Neel Krishnaswami

Douglas Auclair

Use and copying of this software and preparation of derivative works based on this software are permitted, including commercial use, provided that the following conditions are observed:

  • This copyright notice must be retained in full on any copies and on appropriate parts of any derivative works.

  • Documentation (paper or online) accompanying any system that incorporates this software, or any part of it, must acknowledge the contribution of the Gwydion Project at Carnegie Mellon University.

This software is made available "as is". Neither the authors nor Carnegie Mellon University make any warranty about the software, its performance, or its conformity to any specification.

Bug reports, questions, comments, and suggestions should be sent by E-mail to the Internet address .


Table of Contents
1. Introduction
2. The Dylan Library and Gwydion Dylan Extensions
Introduction
Modules of the Dylan Library
The Dylan Module
The Extensions Module
Generally Useful Definitions
Debugger Customizations
Exiting Applications
Collections
Integers
Ratios
The System Module
The Introspection Module
The Cheap-IO Module
3. The Streams Library
Discussing error conditions
Goals of the Library
Concepts
Streams, growing sequences, and object identity
Streams Reference
General Stream Classes and Operations
File Stream Classes and Operations
4. The Standard-IO Library
The Standard-IO Library
5. The Format Library
The Format Module
Format Directives
Simple Example
Examples Using the %m Directive
6. The Format-Out Library
The Format-Out Module
7. The Print Library
Print Module
PPrint Module
8. The Collection-Extensions Library
Introduction
Module self-organizing-list
Module subseq
Module vector-search
Module Sequence-Utilities
Predicate Functions
Creational Functions
Sequence Slicing
Finding Sequence Elements
Mapping and Reducing Functions
Associative Lists
Functions Not Yet Described
9. The table-extensions Library
The table-extensions Module
10. The string-extensions Library
Module character-type
The string-conversions Module
The string-hacking Module
The substring-search Module
11. The Regular-Expressions Library
Regular-expressions Module
Make-Foo vs. Foo Functions
Caching
Exported Names
Known Bugs
12. The Transcendental Library
Sine, Cosine, and Tangent
The pi Constants
The Inverse (Arc) Functions
The Hyperbolic Functions
The e Constants
The Logarithmic Functions
13. The Time Library
The Time Module
The Time-IO Module
Parse-Time Directives
14. The Random Library
The Random Module
15. The Matrix Library
Initialization
Matrix Operations
16. The Parse-Arguments Library
Terminology
A Simple Example
Parsing Arguments
Argument List Parsers
Option Parsers
Parsing an Argument List
Standard Option Parser Classes
Writing New Option Parser Classes
List of Figures
3-1. Streams library classes.
12-1. A right triangle
12-2. A right triangle
16-1. Sample command line.
16-2. Library declaration for a sample application using parse-arguments.
16-3. Source code for a sample application using parse-arguments, making use of the define argument-parser macro.
16-4. Source code for a sample application using parse-arguments.

Chapter 1. Introduction

This manual serves as a guide to the libraries included with Gywdion Dylan ™ . These libraries include:

Dylan

Streams

Standard-IO

Format

Format-Out

Print

Collection-Extensions

Table-Extensions

String-Extensions

Regular-Expressions

Transcendental

Time

Random

Matrix


Chapter 2. The Dylan Library and Gwydion Dylan Extensions

Introduction

In the process of working with Dylan, the Gwydion Project has come up with numerous extensions to the Dylan language. Some of them form entire libraries, like the Collection-Extensions and String-Extensions libraries. Others have been added to the Dylan library, in such modules as Extensions and System.

We continue to make no claims about future support for our extensions. However, some extensions are more likely than others to make it into our future compilers. This file documents those extensions which we think will be included in our compiler's Dylan library.

Extensions which go in separate libraries are documented in their own files; extensions which are part of the Mindy Dylan library but which have a less certain future are documented in the Mindy documentation.

For the remainder of this chapter, we shall refer to "Gwydion compilers" as a shorthand for "Mindy and other Dylan compilers that the Gwydion Project may write." It is not meant as a guarentee that all future Gwydion releases will support these extensions.

Specific Gwydion compilers may support extensions not listed here; see their documentation for details.


Modules of the Dylan Library

In addition to containing the Dylan module, the Dylan library contains a variety of modules which provide extensions. Gwydion compilers export the following modules from the Dylan library:

Extensions

This module exports useful extensions to the Dylan language (see the Section called The Extensions Module). Ultimately, there will be several, more logically separate libraries that extend Dylan or provide an application framework for users. For now, we put any commonly used utilities in the Extensions module.

System

This module exports an interface to operating system calls and special, low-level functionality (see the Section called The System Module).

Introspection

This module exports reflective operations for examining classes, functions, and so on.

Cheap-io

This module exports some basic, unextendable input and output functionality.


The Dylan Module

Whenever possible, we have tried to keep the Dylan module pristine and unextended, prefering to add our extensions to separate modules or libraries. However, this is not always possible, particularly when it involves extending the behavior of a function or macro that is exported from the Dylan module. Currently, Gwydion compilers support these extensions to the Dylan module as described below:

  • Gwydion compilers support keyed-by clauses in for statements. The format of such a clause is

    var keyed-by key in collection

    The var is bound to each element in collection, and key is bound to the element's key value.

  • Gwydion compilers supports using clauses in for statements. The format of such a clause is

    var in collection using protocol

    The protocol will be used instead of forward-iteration-protocol. The protocol argument must be a variable name, not an expression. These using clauses may be used together with keyed-by:

    var keyed-by key in collection using protocol
  • Gwydion compilers have an additional type of top level definition, define function, which creates a constant binding in the current module and initializes it to a new function. The usage of define function usage is similar to that of define method. The following is an example:

    define function cube (x)
      x * x * x;
    end function cube;

    A similar result might be had by writing

    define constant cube = method (x)
                             x * x * x;
                           end method;

    or

    define method cube (x)
      x * x * x;
    end method cube;
  • Gwydion compilers supports subclass specializers via the limited function. A subclass specializer causes a method to be invoked whenever the generic function was called on a value that is the specified class or any subclass of the specified class. The method is never invoked on a value that is an instance (direct or indirect) of the specified class, only when the value is a subclass of the specified class. The following is an example:

    define method make
        (result-class :: limited(<class>, subclass-of: <my-class>));
      let x = next-method();
      do-special-logging-or-something(x);
      x;
    end method;

The Extensions Module

Ultimately, there will be several, more logically separate libraries that extend Dylan or provide an application framework for users. For now, we put any commonly used utilities in the Extensions module.


Generally Useful Definitions

The Extensions module exports the following generally useful functionality:


<byte-vector>[sealed Class]

A <vector> that holds integers between 0 and 255 inclusively

Superclasses

<simple-vector>

Initialization Keywords

fill:An instance of <byte>. The default value of each element Defaults to 0.
size:An instance of <object>. The size of the vector Defaults to 0.

Description

An efficient vector for byte-storage.


<byte-character>[Constant]

An ASCII character.

Type

<byte-character-type>

Description

Characters of this type represent the ASCII character set (or extensions to ASCII such as ISO 8859). Note, in Gwydion compilers the <character> class is equivalent to Unicode characters.


assert[Function]

Signals an error if assumption is incorrect

Synopsis

assert (value) => ()

Parameters

valueAn instance of <object>. A boolean condition which should be #t

Return Values

None.

Description

This function signals an error if value is #f. Otherwise, it does nothing. In future Gwydion compilers, assert may be changed to a macro, which may or may not evaluate its argument exactly once.

Note: So, it goes to follow that users of assert should not have side-effects in the expression that is passed to assert because if we ever turn assertions off, that would mean the program runs differently in debug mode than it does in release mode.


one-of[Method]

Creates a class that is one of the supplied arguments.

Synopsis

one-of (#rest things) => (res)

Parameters

thingsInstances of <object>. The allowable classes

Return Values

resAn instance of <type>. The resulting type from the supplied classes.

Description

This function takes any number of objects, and returns the type that is the type-union of the singletons of those objects. For example, the expression

one-of(#"foo", #"bar", #"baz")

is equivalent to

type-union(singleton(#"foo"), singleton(#"bar"), singleton(#"baz"))

false-or[Method]

Creates a class that is either #f or the supplied class.

Synopsis

false-or (type) => (res)

Parameters

typeAn instance of <object>. The alternate type

Return Values

resAn instance of <type>. The resulting type-union.

Description

This function is useful in type expressions. It captures the common idiom of returning an instance of a particular type or the value #f. The expression

false-or(<integer>)

is equivalent to the expression

type-union(<integer>, singleton(#f))

Debugger Customizations

(A note on terminology: We use the term "debugger" here in the loose, Dylan sense of anything that handles an uncaught error. In Mindy, this debugger is indeed a full fledged debugger, but in other Gwydion compilers it may not be.)

The debugger uses the function report-condition to print conditions as error messages to users; for example, this is the function that implements the %S format-string directive for conditions. The debugger also uses the format function exported from the Cheap-io module to process format strings, and it prints directly to the Unix stdout. If any library that is used itself uses the Debugger-format library, then the debugger uses format from the Format library, which is shipped with Gwydion compilers. You can extend how the debugger prints conditions, change what formatting function it uses, and direct where debugger output goes with the following:


report-condition[open Generic]

Writes a condition to a stream.

Synopsis

report-condition (condition, stream) => ()

Parameters

conditionAn instance of <condition>.
streamAn instance of <object>. As we don't know the underlying output system, we'll accept any object.

Return Values

None.

Description

This is the function that is used to print condition variables as error messages to users. The internal format function used by Mindy uses report-condition for condition arguments to the %S format directive. The Format library's print-message method for conditions calls report-condition.

If you are writing a module that does no output but still provides report-condition methods, you should use condition-format to format output. Using condition-format makes your module more flexible for users of your module. If you call Cheap-IO's format, you'll be forced to write to only one destination, stdout, ignoring the stream argument. If you call the Format library's format function, then your module will require the Format, Print, and Streams libraries; therefore, users of your module may ultimately load these other libraries needlessly. Of course, if you want to make use of the extended functionality of the Format library's format control strings, then you only have one choice anyway, and there's no reason to use condition-format.

Report-condition has several supplied methods. The default method (on <condition>) simply prints the condition (not very descriptive). The <format-string-condtion> (of which the simple conditions are derived) method uses the supplied format-string to output information about the cause of the condition. The <type-error> method gives the expected and actual types, and the <abort> method just prints the supplied description.


condition-format[open Generic]

Serves as a firewall between the condition system and streams.

Synopsis

condition-format (stream, control-string, #rest arguments) => ()

Parameters

streamAn instance of <object>. As we don't know the underlying output system, we'll accept any object.
control-stringAn instance of <string>. The format string to print the condition.
argumentsInstances of <object>.

Return Values

None.

Description

This function serves as a firewall between the condition system and the Streams and Format libraries. Methods on report-condition should use condition-format to do their formatting. Users will generally use *debug-output* or *warning-output* for the stream argument, but this is not required.

Mindy supplies a method for when stream is #"Cheap-IO". The Gwydion Format library supplies a method for when stream is a subclass of <stream>. If you are implementing your own streams or format libraries, you will need to define a method on condition-format for your type of stream.


condition-force-output[open Generic]

Flushes the condition output stream.

Synopsis

condition-force-output (stream) => ()

Parameters

streamAn instance of <object>. As we don't know the underlying output system, we'll accept any object.

Return Values

None.

Description

Condition-force-output forces any pending output from stream's buffer to stream's destination. This function is invoked by the debugger after a condition has been reported and before it pauses for user input. Unless you are writing a debugger, you do not need to call condition-force-output yourself.

Mindy supplies a method for when stream is #"Cheap-IO". The Gwydion Format library supplies a method for when stream is a subclass of <stream>. If you are implementing your own streams or format libraries, you will need to define a method on condition-force-output for your type of stream.


*default-level*[Variable]

Gives how far down recursively to print

Type

<object>

Description

Default-handler for <warning> uses *warning-output* to print warning messages. This variable must be either a <stream> from the Streams library, or #"Cheap-IO" (the default). When this variable is #"Cheap-IO", the output goes to stderr.


Exiting Applications

The Extensions module exports the following functionality for controlling the exiting of applications:


exit[Method]

Causes the application to quit.

Synopsis

exit (#key exit-code) => (res)

Parameters

exit-code:An instance of <integer>. Defaults to 0.

Return Values

resAn instance of <never-returns>.

Description

Causes the process to exit with return code exit-code.


on-exit[Method]

Adds a function to be called just before quitting.

Synopsis

on-exit (function) => ()

Parameters

functionAn instance of <function>. A function to execute before quitting.

Return Values

None.

Description

Arranges for the exit function to call the argument function. The argument function must take no required arguments. Users may call on-exit multiple times to install more than one function for exit to call, but the order in which exit invokes the functions is undefined. Calling on-exit on the same function repeatedly installs that function multiple times.


Collections

The Extensions module exports the following <collection> functionality:


key-exists?[Method]

Returns #t if a key is in a collection.

Synopsis

key-exists? (coll, key) => (result, value)

Parameters

collAn instance of <collection>.
keyAn instance of <object>.

Return Values

resultAn instance of <boolean>.
valueAn instance of <object>. The associated datum for the key

Description

Return whether key is in coll. If the key is in the coll, then the second value is the element associated with key; otherwise, the second return value is #f.


Integers

Gwydion compilers have an abstract class <general-integer> which has two concrete subclasses, <integer> and <extended-integer>. <integer>s have a limited range of values, and <integer> arithmetic uses the computer's underlying integer facilities. <extended-integer>s can take on any value, and are similar to Common Lisp "bignums." Expressions involving <extended-integer>s produce <extendedinteger> results because <extended-integer>s are contagious. If an expression involving only <integer> values would produce a result that does not fit in an <integer>, then the Gwydion compiler will signal an overflow error. You can use the as function to convert back and forth between <integer>s and <extended-integer>s. As signals an error when converting an <extended-integer> to a <integer>, and the value does not fit in a <integer>.

The Extension module exports the following integer functionality:


<general-integer>[abstract Class]

Parent class of all integers.

Superclasses

<rational>

Initialization Keywords

None.

Description

The superclass of <integer> and <extended-integer>.


<extended-integer>[ Class]

An integer of any size.

Superclasses

<general-integer>

Initialization Keywords

None.

Description

A bignum is just a vector of digits.


$maximum-integer[Constant]

Highest computed integer for the architecture.

Type

<integer>

Description

Holds the largest positive <integer>.


$minimum-integer[Constant]

Lowest computed integer for the architecture.

Type

<integer>

Description

Holds the smallest negative <integer>.


Ratios

The Extensions module exports the following:


<ratio>[functional Class]

An exact fractional number.

Superclasses

<rational>

Initialization Keywords

numerator:An instance of <extended-integer>.
denominator:An instance of <extended-integer>. Guaranteed positive.

Description

A ratio has two slots: numerator and denominator. It is normalized so that it has a positive denominator, and the greatest common divisor of the numerator and the denominator is one. Ratios are never automatically converted to integers. For example, ratio(4, 2) would return 2/1.

A numeric operation involving two ratios produces a normalized ratio result. A numeric operation involving a ratio and an integer produced a normalized ratio result. A numeric operation involving a ratio and a float produces a float result.


ratio[Method]

Makes a ratio from to integers.

Synopsis

ratio (num, denom) => (res)

Parameters

numAn instance of <extended-integer>.
denomAn instance of <extended-integer>.

Return Values

resAn instance of <ratio>.

Description

This function makes a ratio from the two integers.


Chapter 3. The Streams Library

Acknowlegements. We'd like to thank the other people who have been instrumental in the production of this proposal: Jonathan Bachrach, Dave Berry, John Dunning, Chris Fry, Paul Haahr, William Lott, Rob Maclachlan, Tim McNerney, Tony Mann, Keith Playford, Robert Stockton, and Tucker Withington.


Discussing error conditions

This document uses two special terms in discussions of error conditions.

When we say that something is an error, we mean that the result is undefined. In particular, we do not mean that a Streams implementation must signal an error condition; that is the implementor's choice. So, for instance, the following text means only that the result of using unread-element in the case described is undefined:

It is an error to apply unread-element to an element that is not the element most recently read from the stream.

Only when we specifically mention signaling do we mean that a Streams implementation must signal an error condition. Note that we may not, in such a case, say exactly which error condition must be signaled; if we do not say so, the choice is again up to the implementor. In the following text, for instance, we state that an implementation must signal an error, but we do not say what error must be signaled:

When position is a <stream-position>, if it is invalid for some reason, this function signals an error.

By contrast, the following text says exactly which error must be signaled:

If the end of the stream is encountered and no value was supplied for on-end-of-stream, read-element signals an <end-of-stream-error> condition.


Goals of the Library

The Dylan Streams library aims to provide:

  • A generic, easy-to-use interface for streaming over sequences and files. The same high-level interface for consuming or producing is available irrespective of the type of stream, or the types of the elements being streamed over.

  • Efficiency, especially for the common case of file I/O.

  • Access to an underlying buffer management protocol.

  • An extensible framework. Other areas of functionality that require a stream interface should be easy to integrate with the library.

The proposal presents the design of a Streams library that meets these goals using Dylan's built-in sequences and a buffered disk file interface.

The proposal does not address a number of related issues, including:

  • A standard object-printing package such as Smalltalk's printOn: or Lisp's print-object, or a formatted printing facility such as Lisp's format. Additional libraries are expected to provide these facilities.

  • General object dumping and loading.

  • A comprehensive range of I/O facilities for using memory-mapped files, network connections, and so on. Such facilities should be easy to add to the Streams library because of its extensible framework.

  • An interface for naming files.

  • An interface to operating system functionality, such as file renaming or deleting operations.


Concepts

A stream provides sequential access to an aggregate of data, such as a Dylan sequence or a disk file. Streams grant this access according to a metaphor of reading and writing: elements can be read from streams or written to them.

Streams are represented as Dylan objects, and all are general instances of the class <stream>, which the Streams library defines.

We say that a stream is established over the data aggregate. Hence, a stream providing access to the string "hello world" is said to be a stream over the string "hello world".

Streams permitting reading operations are called input streams. Input streams allow elements from the underlying data aggregate to be consumed. Conversely, streams permitting writing operations are called output streams. Output streams allow elements to be written to the underlying data aggregate. Streams permitting both kinds of operations are called input-output streams.

The library provides a set of functions for reading elements from an input stream. These functions hide the details of indexing, buffering, and so on. For instance, the function read-element reads a single data element from an input stream.

The following expression binds stream to an input stream over the string "hello world":

let stream = make(<string-stream>, contents: "hello world");

The first invocation of read-element on stream returns the character 'h', the next invocation 'e', and so on. Once a stream has been used to consume all the elements of the data, the stream is said to be at its end. This condition can be tested with the function stream-at-end?. The following code fragment applies function to all elements of the sequence:

let stream = make(<sequence-stream>, contents: seq);
while (~stream-at-end?(stream)) 
	function(read-element(stream));
end;

When all elements of a stream have been read, further calls to read-element result in the <end-of-stream-error> condition being signalled. An alternative end-of-stream behavior is to have a distinguished end-of-stream value returned. You can supply such an end-of-stream value as a keyword argument to the various read functions; the value can be any object. Supplying an end-of-stream value to a read function is more efficient than asking whether a stream is at its end on every iteration of a loop.

The library also provides a set of functions for writing data elements to an output stream. Like the functions that operate upon input streams, these functions hide the details of indexing, growing an underlying sequence, buffering for a file, and so on. For instance, the function write-element writes a single data element to an output stream.

The following forms bind stream to an output stream over an empty string and create the string "I see!", using the function stream-contents to access all of the stream's elements.

let stream = make(<byte-string-stream>, direction: #"output");
write-element(stream, 'I');
write-element(stream, ' ');
write(stream, "see");
write-element(stream, '!');
stream-contents(stream);

Calling write on a sequence has the same effect as calling write-element on all the elements of the sequence. However, it is not required that write be implemented directly in terms of write-element; it might be implemented more efficiently, especially for buffered streams.

Some streams are positionable; that is, they permit random access to their elements. Postionable streams allow you to set the position at which the stream will be accessed by the next operation. The following example uses positioning to return the character 'w' from a stream over the string "hello world":

let stream = make(<string-stream>, contents: "hello world");
stream-position(stream) := 6;
read-element(stream);

The following example returns a string, but the contents of the first ten characters are undefined:

let stream = make(<string-stream>, direction: #"output");
adjust-stream-position(stream, 10); 
write(stream, "whoa!");
stream-contents(stream);

You can request a sequence containing all of the elements of a positionable stream by calling stream-contents on it. The sequence returned never shares structure with any underlying sequence that might be used in future by the stream. For instance, the string returned by calling stream-contents on an output <string-stream> will not be the same string as that being used to represent the string stream.

When making an input <string-stream>, you can cause the stream to produce elements from any subsequence of the supplied string. For example:

read-to-end(make(<string-stream>, 
                 contents: "hello there, world",
                 start: 6, 
                 end: 11));

This example evaluates to "there". The interval (start, end) includes the index start but excludes the index end. This is consistent with standard Dylan functions over sequences, such as copy-sequence. The read-to-end function is one of a number of convenient utility functions for operating on streams and returns all the elements up to the end of the stream from the stream's current position.


Streams, growing sequences, and object identity

When writing to output streams over sequences, Dylan may from time to time need to grow the underlying sequence that it is using to represent the stream data.

Consider the example of an output stream instantiated over an empty string. As soon as a write operation is performed on the stream, it is necessary to replace the string object used in the representation of the string stream. As well as incurring the cost of creating a new string, the replacement operation can affect the integrity of other references to the string within the program.

To guarantee that alias references to a sequence used in an output <sequence-stream> will have access to any elements written to the sequence via the stream, supply a <stretchy-vector> to make. A stream over a stretchy vector will use the same stretchy vector throughout the stream's existence.

For example:

let sv = make(<stretchy-vector>);
let stream = make(<sequence-stream>, 
                  contents: sv, 
                  direction: #"output");
write(stream, #(1, 2, 3, 4, 5, 6, 7, 8, 9));
write(stream, "ABCDEF");
values(sv, stream-contents(stream));

The example returns two values. Each value is the same (\==) stretchy vector:

#[1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F']

If a stretchy vector is not supplied, the result is different:

let v = make(<vector>, size: 5);
let stream = make(<sequence-stream>,
                  contents: v, 
                  direction: #"output");
write(stream, #(1, 2, 3, 4, 5, 6, 7, 8, 9));
write(stream, "ABCDEF");
values(v, stream-contents(stream));

This example returns as its first value the original vector, whose contents are undefined, but the second value is a new vector:

#[1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F']

This difference arises because the output stream in the second example does not use a stretchy vector to hold the stream data. A vector of at least 15 elements is necessary to accommodate the elements written to the stream, but the vector supplied, v, can hold only 5. Since the stream cannot change v's size, it must allocate a new vector each time it grows.


Streams Reference

The exported streams class heterarchy is as follows:

Figure 3-1. Streams library classes.

Except for the classes <stream>, <buffered-stream>, and <positionable-stream>, these are instantiable classes.

Streams, in general, have a host of operations for walking over or changing collections, and file streams have some specific issues of their own. Therefore, we will cover the general stream classes and operations in the Section called General Stream Classes and Operations, and file streams in the Section called File Stream Classes and Operations.


General Stream Classes and Operations

General Stream Classes


<stream>[open abstract Class]

The superclass of all stream classes.

Superclasses

<object>

Initialization Keywords

outer-stream:An instance of <object>.

Description

All other streams inherit from this class


<positionable-stream>[open abstract Class]

It supports the Positionable Stream Protocol

Superclasses

<stream>

Initialization Keywords

None.

Description

Positionable streams allow one to specify from where in the stream to read or to write (see the Section called Positioning Functions).


<stream-position>[abstract Class]

Gives the location in a <positionable-stream>.

Superclasses

<object>

Initialization Keywords

None.

Description

Allows random access to elements in <positionable-stream>s.


<buffered-stream>[Open abstract Class]

Streams that can access multiple elements with a single read/write command.

Superclasses

<stream>

Initialization Keywords

buffer-size:An instance of <integer>. Suggests the size of the underlying collection.

Description

A subclass of <stream> supporting the Stream Extension Protocol and the Buffer Access Protocol. It is not instantiable.

Streams of this class support the buffer-size: init-keyword, which can be used to suggest the size of the stream's buffer. However, the instantiated stream might not use this value: it is taken purely as a suggested value. For example, a stream that uses a specific device's hardware buffer might use a fixed buffer size regardless of the value passed with the buffer-size: init-keyword.


<sequence-stream>[Open instantiable Class]

The class of streams over sequences.

Superclasses

<positionable-stream>

Initialization Keywords

contents:An instance of <object>.
direction:An instance of <object>.
start:An instance of <object>.
end:An instance of <object>.

Description

The <sequence-stream> class can be used for streaming over all sequences, but there are also subclasses <string-stream>, <byte-string-stream>, and <unicode-string-stream>, which are specialized for streaming over strings.


<string-stream>[Open instantiable Class]

The class of streams over strings.

Superclasses

<sequence-stream>

Initialization Keywords

contents:An instance of <object>.
direction:An instance of <object>.
start:An instance of <object>.
end:An instance of <object>.

Description

The superclass of the byte and unicode implementation classes.


<byte-string-stream>[Open instantiable Class]

The class of streams over strings.

Superclasses

<sequence-stream>

Initialization Keywords

contents:An instance of <object>.
direction:An instance of <object>.
start:An instance of <object>.
end:An instance of <object>.

Description

Streams over byte strings.


<unicode-string-stream>[Open instantiable Class]

The class of streams over strings.

Superclasses

<sequence-stream>

Initialization Keywords

contents:An instance of <object>.
direction:An instance of <object>.
start:An instance of <object>.
end:An instance of <object>.

Description

Streams over unicode strings


General Stream Functions

There are make methods on <sequence-stream>, <string-stream>, <byte-string-stream> and <unicode-string-stream>. The make methods on <sequence-stream> and <string-stream> might not create direct instances of those classes, but instead an instance of a subclass determined by type-for-sequence-stream.


type-for-sequence-stream[open Generic]

Returns a stream depending on the sequence.

Synopsis

type-for-sequence-stream (seq) => (sequence-stream-type)

Parameters

seqAn instance of <sequence>.

Return Values

sequence-stream-typeAn instance of <type>.

Description

Called by make. Returns a type for creating a <sequence-stream>.


close[open Generic]

Closes a stream.

Synopsis

close (stream, #key #all-keys) => ()

Parameters

streamAn instance of <stream>.

Return Values

None.

Description

Streams are automatically opened when created, and closed when they go out of scope. But, sometimes it is necessary to close a stream immediately (for example, to open another one over the same sequence but in the opposite direction). This function provides for that necessity.


Reading Functions

From a stream, one can read one element, a number of elements, or a line at a time.


read-element[open Generic]

Reads the next element from the stream.

Synopsis

read-element (stream, #key on-end-of-stream) => (element-or-eof)

Parameters

streamAn instance of <stream>.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.

Return Values

element-or-eofAn instance of <object>.

Description

Reads the next element from the stream and advances the stream's position.

When the stream is past the end of the contents, two possible results occur. If the caller supplied a value to the on-end-of-stream: keyword, then that value is returned. Otherwise, read-element throws an <end-of-stream-error>.


unread-element[open Generic]

Backs up the stream by one element.

Synopsis

unread-element (stream, elemnt) => (the-elemnt)

Parameters

streamAn instance of <stream>.
elemntAn instance of <object>. What the previous element should be.

Return Values

the-elemntAn instance of <object>.

Description

Backs up the stream by one element. In some methods this function will ensure that elemnt is at the stream's position. If it isn't then unread-element will signal an error. Otherwise, it will return elemnt.

Note: One must be careful about using element as a variable name, for Dylan uses the function element to resolve element access of sequences with the bracket syntax (i.e. [ and ]). Results can be unpredicable when one has a local binding to element and also indexes into sequences with the bracket syntax.


peek[open Generic]

Retrieves the next element from the stream.

Synopsis

peek (stream, #key on-end-of-stream) => (element-or-eof)

Parameters

streamAn instance of <stream>.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.

Return Values

element-or-eofAn instance of <object>.

Description

Reads the next element from the stream but does not advance the stream's position. Handles end-of-stream conditions just as read-element does.


read[open Generic]

Reads in a group of elements from a stream.

Synopsis

read (stream, n, #key on-end-of-stream) => (sequence-or-eof)

Parameters

streamAn instance of <stream>.
nAn instance of <integer>. Number of elements to read.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.

Return Values

sequence-or-eofAn instance of <object>.

Description

Reads in n elements from the stream starting from the the stream's current position. The type of the collection returned depends on the collection underlying the stream. Handles end-of-stream conditions just as read-element does.


read-into![open Generic]

Reads a group of elements from a stream into a collection.

Synopsis

read-into! (stream, n, sequence, #key start, on-end-of-stream) => (count-or-eof)

Parameters

streamAn instance of <stream>.
nAn instance of <integer>. Number of elements to read.
sequenceAn instance of <mutable-sequence>. Note: this sequence must allow for changes in its size.
start:An instance of <object>. What index to start writing into the sequence. Defaults to 0.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.

Return Values

count-or-eofAn instance of <object>. Number of elements transferred.

Description

Reads in n elements from the stream starting from the the stream's current position and places those elements into sequence. Sequence must be mutable to allow it to expand should the streamed in elements be larger than its original size. Handles end-of-stream conditions just as read-element does.


read-line[open Generic]

Reads a line of elements from a stream.

Synopsis

read-line (stream, #key on-end-of-stream) => (sequence-or-eof, newline?)

Parameters

streamAn instance of <stream>.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.

Return Values

sequence-or-eofAn instance of <object>.
newline?An instance of <object>.

Description

Reads in one line of elements from the stream starting from the the stream's current position. The type of the collection returned depends on the collection underlying the stream. Handles end-of-stream conditions just as read-element does.

The second return value will be #f when the end of the stream is discovered before a newline, and #t otherwise.


read-line-into![open Generic]

Reads a line of elements from a stream into a collection.

Synopsis

read-line-into! (stream, string, #key start, on-end-of-stream, grow?) => (string-or-eof, newline?)

Parameters

streamAn instance of <stream>.
stringAn instance of <string>. Note: this sequence must allow for changes in its size when grow? is #t.
start:An instance of <object>. What index to start writing into the sequence. Defaults to 0.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.
grow?:An instance of <object>. Whether to grow the supplied sequence. Defaults to #f.

Return Values

string-or-eofAn instance of <object>. The string containing the line, or on-end-of-stream.
newline?An instance of <object>. #f when end of stream was reached before a newline.

Description

Reads in a line of elements from the stream starting from the the stream's current position and places those elements into sequence. Sequence must be mutable to allow it to expand should the streamed in elements be larger than its original size when grow?: is #t. Handles end-of-stream conditions just as read-element does.


discard-input[open Generic]

Discards the elements from the stream.

Synopsis

discard-input (stream) => ()

Parameters

streamAn instance of <stream>.

Return Values

None.

Description

"Reads" in all the elements, and then discards them. The actual action depends on which method of this function does the work. The default implementation does nothing, other implementations advance the stream's position to the end of the collection.


stream-input-available?[open Generic]

Checks the stream if it's available for reading.

Synopsis

stream-input-available? (stream) => (input-available?)

Parameters

streamAn instance of <stream>.

Return Values

input-available?An instance of <boolean>.

Description

Checks if the stream is available for reading.


Convenience Reading Functions

Conveniece functions for reading from streams. These functions are implemented in terms of the more primitive functions defined above.


read-to[Method]

Reads in a group of elements from a stream up to a marker element.

Synopsis

read-to (stream, elemnt, #key on-end-of-stream, test) => (sequence-or-eof, found?)

Parameters

streamAn instance of <stream>.
elemntAn instance of <object>. The element to read up to.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.
test:An instance of <function>. Comparator for elemnt and the stream's contents. Defaults to \==.

Return Values

sequence-or-eofAn instance of <object>.
found?An instance of <boolean>.

Description

Reads in as many elements from the stream starting from the the stream's current position until it reaches elemnt. Returns the matching sequence and #t if elemnt was in the stream. If read-to does not find elemnt (using the function supplied to test:), it will handle end-of-stream conditions as read-element.


read-through[Method]

Reads in a group of elements from a stream up to and including a marker element.

Synopsis

read-through (stream, elemnt, #key on-end-of-stream, test) => (sequence-or-eof, found?)

Parameters

streamAn instance of <stream>.
elemntAn instance of <object>. The element to read up to.
on-end-of-stream:An instance of <object>. Value returned if reading past the stream. Defaults to $not-supplied.
test:An instance of <function>. Comparator for elemnt and the stream's contents. Defaults to \==.

Return Values

sequence-or-eofAn instance of <object>.
found?An instance of <boolean>.

Description

Just as read-to, but this function also returns the marker element as part of the sequence returned.


Querying Functions

stream-open?[open Generic]

Checks to see if a stream is open.

Synopsis

stream-open? (stream) => (open?)

Parameters

streamAn instance of <stream>.

Return Values

open?An instance of <boolean>.

Description

If there's contents available for the stream, then it's open.


stream-element-type[open Generic]

Returns the type of elements streamed over.

Synopsis

stream-element-type (stream) => (element-type)

Parameters

streamAn instance of <stream>.

Return Values

element-typeAn instance of <type>.

Description

For most streams, that are type-declarative (e.g. <byte-string-stream>), this simply returns the underlying element-type. For generic <sequence>s, the method must have at least one element (the first) to return a type.


stream-at-end?[open Generic]

Sees if the stream is at the end.

Synopsis

stream-at-end? (stream) => (at-end?)

Parameters

streamAn instance of <stream>.

Return Values

at-end?An instance of <boolean>.

Description

Checks to see if the stream is at the end of its contents.

Note: It is a bit faster to supply a value to the on-end-of-stream key for read or write than to use this function in a loop.


Positioning Functions

stream-position[open Generic]

Gives the position of a stream.

Synopsis

stream-position (stream) => (position)

Parameters

streamAn instance of <positionable-stream>.

Return Values

positionAn instance of type-union(<stream-position>, <integer>) .

Description

Safely returns the stream's position (even if it's locked).


stream-position-setter[open Generic]

Sets the position of a stream.

Synopsis

stream-position-setter (pos, stream) => (new-position)

Parameters

posAn instance of type-union(<stream-position>, <integer>, one-of(#"start", #"end")) .
streamAn instance of <positionable-stream>.

Return Values

new-positionAn instance of type-union(<stream-position>, <integer>) .

Description

Sets the stream's position to a new absolute position. Allows #"start", #"end", or a <stream-position> as the position-setter.


adjust-stream-position[open Generic]

Sets the relative position of a stream.

Synopsis

adjust-stream-position (stream, delta, #key from) => (new-position)

Parameters

streamAn instance of <positionable-stream>.
deltaAn instance of <integer>. The distance to move.
from:An instance of one-of(#"current", #"start", #"end"). The position from where to move.

Return Values

new-positionAn instance of type-union(<stream-position>, <integer>) . The new position in the stream.

Description

Sets the stream's position to a new relative position, either from the current position or from either end of the stream.


stream-size[open Generic]

Returns the stream's size.

Synopsis

stream-size (stream) => (size)

Parameters

streamAn instance of <positionable-stream>.

Return Values

sizeAn instance of <integer>.

Description

Returns the size of the stream.


stream-contents[open Generic]

Returns the stream's contents.

Synopsis

stream-contents (stream, #key clear-contents?) => (contents)

Parameters

streamAn instance of <positionable-stream>.
clear-contents?:An instance of <boolean>. If #t, clear the stream after returning the contents.

Return Values

contentsAn instance of <sequence>.

Description

Returns the contents of the stream.


File Stream Classes and Operations

Class File-Stream


<file-stream>[Open abstract Class]

The class of streams over disk files.

Superclasses

<buffered-stream> <positionable-stream>

Initialization Keywords

locator:An instance of <string>. The file name. If the Locators library is in use, locator should be an instance of <locator> or a string that can be coerced to one.
direction:An instance of one-of(#"input", #"output", #"input-output") .
if-exists:An instance of one-of(#f, #"new-version", #"overwrite", #"replace", #"append", #"truncate", #"signal") . An action to take if the file already exists.
if-does-not-exist:An instance of one-of(#f, #"signal", #"create") . An action to take if the file doesn't exists.
element-type:An instance of <type>. What kind of file (usually <byte> or <byte-character>).

Description

When you instantiate this class, an implementation-dependent, indirect instance of it is created (from a call to type-for-file-stream). The file being streamed over is opened immediately upon creating the stream.

File streams are intended only for accessing the contents of files. They are not intended to provide a general file handling facility of renaming, deleting, moving, parsing directory names and so on. If you wish to do these kinds of operations, use the File-System library instead.

If an implementation checks file permissions when creating and opening file streams, and it detects an attempt to read a file for which the user has no read permission, or to write a file for which the user has no write permission, then an <invalid-file-permissions-error> condition is signalled at the time the file stream is created.

Because creating a file stream always involves an attempt to open the underlying file, the aforementioned error conditions will occur during file stream instance initialization.

The element-type init-keyword specifies the type of the elements in the file named by locator. This allows file elements to be represented abstractly; for instance, contiguous elements could be treated as a single database record. This init-keyword defaults to something useful, potentially based on the properties of the file; <byte-character> and <unicode-character> are likely choices.

The optional if-exists: init-keyword allows you to specify an action to take if the file named by locator already exists. The options are:

  • #f -- No action. This is the default when the stream's direction is #"input" or #"input-output".

  • #"new-version" -- If the underlying file system supports file versioning, a new version of the file is created. This is the default when the stream's direction is #"output".

    If the file system does not support file versioning, the implementation should substitute one of the other if-exists: behaviors; the #"replace" behavior is a good choice.

  • #"overwrite" -- Set the stream's position to the beginning of the file, but preserve the current contents of the file. This is useful when the direction is #"input-output" and you want to overwrite an existing file.

  • #"replace" -- Delete or rename the existing file and create a new file.

  • #"append" -- Set the stream's initial position to the end of the existing file so that all new output occurs at the end of the file.

  • #"truncate" -- If the file exists, it is truncated, setting the size of the file to 0. If the file does not exist, create a new file.

  • #"signal" -- Signal a <file-exists-error> condition.

The optional if-does-not-exist: init-keyword allows you to specify an action to take if the file named by locator does not exist. The options are:

  • #f -- No action.

  • #"signal" -- Signal a <file-does-not-exist-error> condition. This is the default when the stream's direction is #"input".

  • #"create" -- Create a new zero-length file. This is the default when the stream's direction is #"output" or #"input-output".

There are some implementation and portability notes dealing with file streams, particularly dealing with the element-type: keyword.

Implementation Note: Ideally, element-type could be any valid Dylan type such as limited(<integer>, min: 0, max: 255) or <unicode-character>. This approach may make it possible to implement a potentially inefficient but general set of file streams. Unfortunately the current language definition does not include adequate support for this approach, so we specify instead an interim minimum set of three element types. The element types are for the time being exported from the streams module of the Streams library.

The three possible element types are:

  • <byte-character> -- The file is accessed as a sequence of 8-bit characters.

  • <unicode-character> -- The file is accessed as a sequence of 16-bit Unicode characters.

  • <byte> -- The file is accessed as a sequence of unsigned 8-bit integers.

Portability Note: Portable code can count on the existence of these three element types, but implementations are free to provide more.


File Stream Functions

All the operations described in the Section called General Stream Functions work with file streams. The following functions are specific to file streams.


type-for-file-stream[open Generic]

Returns the kind of file-stream class to instantiate for a given file.

Synopsis

type-for-file-stream (locator, element-type, encoding) => (type)

Parameters

locatorAn instance of type-union(<locator>, <string>). The file over which to stream
element-typeAn instance of false-or(<type>). The kind of file
encodingAn instance of false-or(<type>).

Return Values

typeAn instance of <type>. The file-stream type.

Description

The method for make on <file-stream> calls this function to determine the class of which it should create an instance.


with-open-file[Statement Macro]

Works on an open file.

Synopsis

with-open-file (stream = name, #rest parameters) body end

Parameters

streamVariable.
nameExpression.
parametersInstances of <object>. Arguments for make to open the file.

Description

Opens a file named name, giving the variable stream to body to perform the stream operations. It then closes the file when body finishes.

Note: Only the stream variable is visible to body. Body sees neither name nor parameters.

For example, the below code snippet looks for someone with Dylan in their resume:

let line = "";
let dylan-experience = #f;
 
with-open-file(file = "resume.txt")
  while(line & ~ dylan-experience)
    dylan-experience := regexp-position(line, "dylan");
    line := read-line(file, on-end-of-stream: #f);
  end while;
end;
 
format-out(if(dylan-experience) 
            "Hire this person now!\n" 
           else 
            "Try someone else\n"
           end if);

Chapter 4. The Standard-IO Library

The Standard-IO Library

The standard-IO module of the standard-IO library exports three names for the standard input, output, and error streams.


*standard-error* [Constant]

The <stream> instance corresponding to the standard error.

Type

<stream>

Description

The standard error <stream>. This usually represents the terminal; however most UNIX-like operating systems permit the standard error stream to be redirected at the command line.


*standard-input* [Constant]

The <stream> instance corresponding to the standard input.

Type

<stream>

Description

The standard input <stream>. Usually, this stream reads from the terminal for its data; however most UNIX-like operating systems permit the standard input stream to be redirected at the command line.


*standard-output* [Constant]

The <stream> instance corresponding to the standard output.

Type

<stream>

Description

The standard output <stream>. This usually represents the terminal (just like *standard-error* ); however most UNIX-like operating systems permit the standard output stream to be redirected at the command line.


Chapter 5. The Format Library

The Format library provides a way to control output to a stream.


The Format Module


format [Generic]

Format a string and write it to a stream.

Synopsis

format ( stream , control-string , #rest args ) => ()

Parameters

stream An instance of <stream>.
control-string An instance of <string>.
args Instances of <object>. The objects to substitute for the format fields.

Return Values

None.

Description

The format function takes a control string, formats according to the format directives embedded in the string, and then writes the result to the stream argument.

The format codes accepted by format are described in the format directives section.


format[Method]

Format a string and write it to a stream.

Synopsis

format ( stream , control-string , #rest args) => ()

Parameters

stream An instance of <stream>.
control-string An instance of <string>.
argsInstances of <object>. The objects to substitute for the format fields.

Return Values

None.

Description

The default format method, specialized on the <stream> class.


format-to-string[Function]

Process a format-string and return the result as another string.

Synopsis

format-to-string ( control-string , #rest args ) => ( result )

Parameters

control-string An instance of <string>.
args Instances of <object>. The objects to substitute for the format fields.

Return Values

result An instance of <string>.

Description

This function effectively calls format and returns the result as a string.


print-message [ Open Generic]

This method is called to format objects for the "%s" and "%c" format operators, in a form suitable for human readers.

Synopsis

print-message (object, stream) => ()

Parameters

objectAn instance of <object>.
streamAn instance of <stream>.

Return Values

None.

Description

Prints object to stream. This generic function is intended to define the human-readable printing behavior of a Dylan object, as opposed to their representation as literal syntax. Calling this function on <condition> should result in a error message, rather than the name of the instance and its class, for example. (Contrast this behavior with the print function in the Print library.)

Predefined methods exist for the <string> , <character> , <condition> , and <symbol> classes.


Format Directives

The format directives are described below:

Directive -- Argument Type -- Textual Format

  • %d -- <integer> -- decimal number

  • %b -- <integer> -- binary number

  • %o -- <integer> -- octal number

  • %x -- <integer> -- hexadecimal number

  • %c -- <character> -- character (with no quotes)

  • %s -- <string> -- string (with no quotes)

  • %s -- <condition> -- condition message (with no quotes)

  • %= -- <object> -- unspecified, but works with any object

  • %% -- none -- literal %

  • %m -- <function> -- a function that accepts the stream as an argument and performs user-defined operations on the stream

The last format directive (%m) is specific to GwydionDylan. See the below examples for using some of the format directives.


Simple Example

Here we use three format directives to print the following message:

Hello, my name is Doug Auclair, and I'm 33 years old.
      

The code to generate the above message is:

format(*standard-output*, "Hello, my name is %s, and I'm %d years old.%c",
       "Doug Auclair", 33, '\n');
      

Note: sending the new-line character ('\n') works as expected on supported platforms, but some systems that require a "\r\n" or a "\n\r" pair for a new-line command may have problems. The preferred way to write the above code is:

format(*standard-output*, "Hello, my name is %s, and I'm %d years old.\n",
       "Doug Auclair", 33);
      

Examples Using the %m Directive

Below are two examples that use the %m directive (and others) to format messages for display.


Simple Example Using the %m Directive

Instead of feeding the (in some cases, troublesome) '\n' character to the %c directive, let us explicitly use the new-line (a function in the Streams library) in concert with the %m directive, like this:

format(*standard-output*, "Hello, my name is %s, and I'm %d years old.%m",
       "Doug Auclair", 33, new-line);
        

The above code produces the same output as the simple example given previously.

Interestingly, Dylan automatically converts '\n' characters in the control string to calls to new-line. (So, neither "%m" => new-line nor "%c" => '\n' mappings are necessary ... Dylan takes care of that).


Complex Example Using the %m Directive

Here we generate almost the same message, this time with a little more information (the current time in Washington D.C.) using the "%m" format directive. The new message is:

Hello, my name is Doug Auclair, and as of
now, November 17, 2000 09:28 PM, I'm 33 years old.
        

To get the above message, we must first create a function that manipulates a <decoded-time> (See the Section called The Time Module in Chapter 13 and the Section called The Time-IO Module in Chapter 13) as we desire for the output:

define function human-readable-time(stream :: <stream>,  
                                    time :: <decoded-time>)
 => ()
    format-time(stream, "%B %d, %Y %H:%M %p", time);
end function human-readable-time;
        

Then we use that function as an argument to the %m directive to produce the message:

format(*standard-output*, "Hello, my name is %s, and as of\n"
                          "now, %m, I'm %d years old\n",
       "Doug Auclair", 
       rcurry(human-readable-time, get-current-time(timezone: 5 * 3600)),
       33);
        

There are several things of note in the above example.

  • First, a short-hand for format(*standard-output*, ... is the format-out function found in the Section called The Format-Out Module in Chapter 6.

  • Second, two strings placed side-by-side (no commas) are concatenated, so

    format(*standard-output*, "%s " "was " "here.\n", "Doug");
                

    is the same as

    format(*standard-output*, "%s was here.\n", "Doug");
                
  • Third, rcurry is a function that takes a function and various arguments to create a new function. A description of it is available in the Dylan Reference Manual (page 349). In this case, rcurry takes the function we created (human-readable-time) and the result of get-current-time (a function in the Time module, that, here, sets the timezone to Z+5 (hours), or Eastern Standard Time) as an argument that creates a new function that expects a <stream> instance to do its work.

  • Fourth, note that in the control string I use '\n' characters. This is the preferred, and simplest, way to request a new-line.

With the above points in mind, one can use the %m directive to integrate complex stream manipulation with the format function.


Chapter 6. The Format-Out Library

The Format-Out library is designed to provide a simple interface to the Format library. It exports the module Format-Out and re-exports the Format and Standard-IO modules from the Format and Standard-IO libraries respectively.


The Format-Out Module

The Format-Out module exports one function format-out.


format-out[Method]

Formats arguments to *standard-output*.

Synopsis

format-out (control-string, #rest args) => ()

Parameters

control-stringAn instance of <string>.
argsInstances of <object>. The objects to substitute for the format fields.

Return Values

None.

Description

Performs

apply(format, *standard-output*, control-string, args);

Chapter 7. The Print Library

The Print library was designed by the Gwydion Project at Carnegie Mellon University. This library provides an interface that outputs an object in Dylan literal syntax if the object can be represented as a Dylan literal, and otherwise, outputs the object in an implementation-dependent manner. There are essentially two functions, print and print-object. The print function accepts keyword arguments that form a print request, controlling features such as circular printing, how deep within a data structure to print, how many elements in long sequences to print before using an ellipsis notation, whether pretty printing is desired, and so on. Users extend print's ability to print various objects by adding methods to the print-object function. The print function handles most of the overhead to satisfy special print requests, outputting any special notations required, and it only calls print-object when it is necessary to print objects. Users should always call the print function to output objects, especially recursively from within print-object methods to output an object's components. Users should never call print-object directly.


Print Module

The Print module provides ways to print objects. It also provides printing properties (depth, circular, etc), and inspection of those properties.


print[Method]

Prints an object on a stream

Synopsis

print (object, stream, #key level, length, circle?, pretty?) => ()

Parameters

objectAn instance of <object>.
streamAn instance of <stream>.
level:An instance of <integer-or-false-or-not-supplied>. Holds the maximum depth to which the user wants recursive printing to go. Defaults to $not-supplied.
length:An instance of <integer-or-false-or-not-supplied>. Holds the maximum number of elements the user wants a sequence to be printed. This does not apply to some sequences, such as strings. Defaults to $not-supplied.
circle?:An instance of <boolean-or-not-supplied>. Defines print behavior when printing a circular list Defaults to $not-supplied.
pretty?:An instance of <boolean-or-not-supplied>. Whether the user wants pretty printing. Defaults to $not-supplied.

Return Values

None.

Description

Prints object to stream according to the print request formed by the keyed arguments. A first call to print creates a printing stream to represent the print request, and recursive calls to print on this printing stream process the keyed arguments differently (see below). There are inspection functions for querying the print request (see their descriptions below). When print actually prints an object, it calls print-object. Though the inspection functions for querying the print request allow you to inspect any parameter of the print request, print-object methods should only need to call print-length. All other aspects of the print request are handled by print. There is one exception which is described in the PPrint module (pretty-printing).

Level controls how deep into a nested data structure to print. The value #f indicates that there is no limit. The default, *default-level*, has no effect on recursive calls to print. Recursive calls to print may change the value of print-level explicitly, but print always uses a value to ensure the print request formed by the first call to print is never exceeded. For example, if a first call to print set the level to 5, and while at a depth of 3, a recursive call specified a level of 4, the recursive call would only descend 2 more levels, not 4.

Length controls how many elements of a sequence to print before printing ellipsis notation (...). The value #f indicates that there is no limit. The print-length control can be interpreted loosely by some print-object methods to control how many elements of any kind of object to print; for example, the default <object> method might regard print-length to determine how many slot-name/value pairs to print. The default, *default-length*, has no effect on recursive calls to print. Recursive calls to print may change the value of print-length explicitly, but they may only decrease the value, never increase it.

Circle? indicates whether printing should check all subcomponent references to make sure the printing process does not infinitely recurse through a data structure. Circular printing also tags objects that occur more than once when they are first printed, and later occurrences are printed as a reference to the previously emitted tag. The default, *default-circle?*, has no effect on recursive calls to print. If print-circle? is already #t, then it remains #t throughout all recursive calls. If print-circle? is #f, then recursive calls to print can change the value to #t; however, when printing exits the dynamic scope of the call that changed the value to #t, the value reverts to #f. If the original call to print specifies circle? as #f, and dynamically distinct recursive calls turn circular printing on and off, all output generated while circular printing was on shares the same tagging space; that is, if #1# is printed twice, once from each of two distinct recursive calls to print, then each #1# is guaranteed to signify the same \== object.

Pretty? indicates whether printing should attempt to insert line breaks and indentation to format objects according to how programmers tend to find it easier to read data. The default, *default-pretty?*, has no effect on recursive calls to print. If print-pretty? is already #t, then it remains #t throughout all recursive calls. If print-pretty? is #f, then recursive calls to print can change the value to #t; however, when printing exits the dynamic scope of the call that changed the value to #t, the value reverts to #f.


print-object[Method]

The default way to print objects

Synopsis

print-object (object, stream) => ()

Parameters

objectAn instance of <object>.
streamAn instance of <stream>.

Return Values

None.

Description

Users extend print's ability to print various objects by adding methods to the print-object function. When print actually prints an object, it calls print-object. Users should never call print-object directly.

Provides the printed object representation for print and for the "%=" format directive (see the Section called Format Directives in Chapter 5). Default print-object methods exist for instances of <object>, <character>, <string>, <list>, <vector>, <sequence>, <array>, <table>, <range>, <function>, <singleton>, <limited-integer>, <union>, <symbol>, <general-integer>, <integer>, <ratio>, <single-float>, <double-float>, <extended-float>, <class>, and for #t and #f.

Users may choose to modify the printed representation in two ways: override the print-object method for that instance's type, or provide a printing function to the "%m" directive for format or format-out.


print-to-string[Method]

Creates a string that contains a printed object representation

Synopsis

print-to-string (object, #key level, length, circle?, pretty?) => (result)

Parameters

objectAn instance of <object>.
level:An instance of <integer-or-false-or-not-supplied>. Holds the maximum depth to which the user wants recursive printing to go. Defaults to $not-supplied.
length:An instance of <integer-or-false-or-not-supplied>. Holds the maximum number of elements the user wants a sequence to be printed. This does not apply to some sequences, such as strings. Defaults to $not-supplied.
circle?:An instance of <boolean-or-not-supplied>. Defines print behavior when printing a circular list Defaults to $not-supplied.
pretty?:An instance of <boolean-or-not-supplied>. Whether the user wants pretty printing. Defaults to $not-supplied.

Return Values

resultAn instance of <byte-string>.

Description

Calls print to produce output according to the print request formed by the keyed arguments and returns the output as a string.

The above print functions use or set the below exported variables to accomplish their work (#f (the default value of all these variables) indicates there is no bounds for the variable):


*default-level*[Variable]

Gives how far down recursively to print

Type

false-or(<integer>)

Description

If a number is given, print prints a # when it reached the level.


*default-length*[Variable]

How many elements to print of a sequence

Type

false-or(<integer>)

Description

If a number is given, print prints a ... to indicate that it reached the maximum number of printable elements.


*default-circle?*[Variable]

What to do for circular lists

Type

<boolean>

Description

If on, prints identical objects as, e.g.: #1#


*default-pretty?*[Variable]

Formats outputted object

Type

<boolean>

Description

If on, prints object indented with proper line breaks, according to the formatting specifications given to pprint-logical-block.

The below functions give printing information on <stream>s. It seems, however, that these functions are neither used nor implemented, as they all give #f or 0 as their response, no matter the <stream>.


print-length[Method]

Always returns #f

Synopsis

print-length (stream) => (length)

Parameters

streamAn instance of <stream>.

Return Values

lengthAn instance of false-or(<integer>).

Description

Returns the current value for the print request. See the print function for details.


print-level[Method]

Always returns #f

Synopsis

print-level (stream) => (level)

Parameters

streamAn instance of <stream>.

Return Values

levelAn instance of false-or(<integer>).

Description

Returns the current value for the print request. See the print function for details. Users should have little use for this function because print takes care to call print-object only when the print level has not been exhausted.


print-depth[Method]

Always returns 0

Synopsis

print-depth (stream) => (depth)

Parameters

streamAn instance of <stream>.

Return Values

depthAn instance of <integer>.

Description

Returns the current depth to which printing has descended into the object on which print was originally called. Print takes care to call print-object only when the print depth has not been exhausted.


print-pretty?[Method]

Always returns #f

Synopsis

print-pretty? (stream) => (pretty?)

Parameters

streamAn instance of <stream>.

Return Values

pretty?An instance of #f.

Description

Returns whether pretty printing is on. Users should have little use for this function (see the Section called PPrint Module).


print-circle?[Method]

Always returns #f

Synopsis

print-circle? (stream) => (circle?)

Parameters

streamAn instance of <stream>.

Return Values

circle?An instance of #f.

Description

Returns whether circular printing is on. Users should have little use for this function because print takes care to detect circularities, tag multiply referenced objects, and emit tags rather than descending into objects to repeatedly print them.


PPrint Module

The Print library implements most of the pretty printing technology described by Richard C. Waters in Common Lisp The Language, second edition. The interface is slightly different because Mindy does not have macros. This section only summarizes the pretty printing functionality to provide a quick reference for users of the Print library, and readers should refer to the Common Lisp manual for more details.

When writing print-object methods, users can ignore whether pretty printing is in effect. If you write your print-object method using pretty printing functions, then when pretty printing is in effect, the output will be pretty printed. When pretty printing is not in effect, your method will produce output as though you had not written it to use pretty printing. All print-object methods that are written to do pretty printing must call the pretty printing functions within the dynamic scope of a call to pprint-logical-block; otherwise, the pretty printing functions are no-ops.


*default-line-length*[Variable]

The length of a single line

Type

<integer>

Description

This is the line length used by the pretty printer to determine how much output will fit on a single line. It defaults to 80.


*print-miser-width*[Variable]

Controls miser mode for pretty printing

Type

false-or(<integer>)

Description

Whenever a logical block (see pprint-logical-block) begins in a column of output that is greater than *default-line-length* - *print-miser-width*, then pretty printing is in miser mode. The value must be an integer or #f (the default). #f indicates that the pretty printer should never enter miser mode.


<pretty-stream>[sealed Class]

Stream used for pretty printing.

Superclasses

<buffered-stream>

Initialization Keywords

target:An instance of <stream>. The stream where the output is finally going to go.
line-length:An instance of <column>. The line length for this stream (0 minimum). Defaults to *default-line-length*.
column:An instance of <column>. The column the first character in the buffer will appear in. Normally zero, but if we end up with a very long line with no breaks in it we might have to output part of it. Then this will no longer be zero. Defaults to 0.

Description

This is a working class for pretty-printing objects. Use an instance of this class when doing a great deal of pretty printing.


pprint-logical-block[Generic]

Start a logical block, creating a pretty-stream if necessary.

Synopsis

pprint-logical-block (stream, #key column, prefix, per-line-prefix, body, suffix) => ()

Parameters

streamAn instance of <stream>.
column:An instance of <integer>.
prefix:An instance of <byte-string>.
per-line-prefix:An instance of <byte-string>.
body:An instance of <function>.
suffix:An instance of <byte-string>.

Return Values

None.

Description

This function groups printing into a logical block. The logical block provides boundaries for new levels of indentation, affects #"linear" newlines, and so on. Prefix is a string to print at the beginning of the logical block. The blocks indentation is automatically set to be one character position greater than the column in which prefix ends. Alternatively, per-line-prefix is a string to print on every line of the logical block. This function signals an error if it is called with both prefix and per-line-prefix supplied as non-#f. Suffix is a string to print at the end of the logical block. Column advises the pretty printer as to the current column of the output stream (defaults to zero). The column argument may be ignored entirely by some methods, and it may be ignored in some cases by methods that can better determine the stream's current output column.

Body must be a <function> that can take one argument, and this argument is a <stream>. The body function should use the stream argument passed to it; the body function should not close over the stream argument to pprint-logical-block. Pprint-logical-block wraps stream with a pretty printing stream when stream is any other kind of stream. If stream is already a pretty printing stream, then the body function is called on stream.

All print-object methods that are written to do pretty printing must call the other pretty printing functions within the dynamic scope of a call to pprint-logical-block; otherwise, the pretty printing functions are no-ops.


pprint-newline[Method]

Output a conditional newline of some kind. If called on a regular stream, ignore it.

Synopsis

pprint-newline (kind, stream) => ()

Parameters

kindAn instance of <pretty-newline-kind>.
streamAn instance of <stream>.

Return Values

None.

Description

This function announces a conditional newline to the pretty printer. The pretty printer emits a newline depending on the kind and the state of the pretty printer's current line buffer. The kind argument has roughly the following meanings:

  • #"fill": Emit a newline if the current section of output does not fit on one line.

  • #"linear": Emit a newline if any #"linear" newline in the current section needs to be emitted. That is, if a current section of output cannot fit on one line, and any one of the #"linear" newlines in the section needs to be emitted, then emit them all.

  • #"miser": Emit a newline as if it were a #"linear" newline, but only when miser mode is in effect. Miser style is in effect when a logical block starts past a particular column of output.

  • #"mandatory": Emit a newline always. Establish that any containing sections cannot be printed on a single line so that #"linear" and #"miser" newlines will be emitted as appropriate.


pprint-indent[Method]

Change the indentation. If called on a regular stream, just ignore it.

Synopsis

pprint-indent (relative-to, n, stream) => ()

Parameters

relative-toAn instance of <indentation-kind>.
nAn instance of <integer>.
streamAn instance of <stream>.

Return Values

None.

Description

This function specifies the indentation to use within the current logical block. When relative-to is #"block", then pprint-indent sets the indentation to the column of the first character of the logical block plus n. When relative-to is #"current", then pprint-indent sets the indentation to the current column plus n.


pprint-tab[Method]

Output a tab. If called on a regular stream, ignore it.

Synopsis

pprint-tab (kind, colnum, colinc, stream) => ()

Parameters

kindAn instance of <tab-kind>.
colnumAn instance of <integer>.
colincAn instance of <integer>.
streamAn instance of <stream>.

Return Values

None.

Description

This function announces a tab to the pretty printer. Colnum and colinc have meaning based on the value of kind:

  • #"line": Tab to output column colnum. If the output is already at or beyond colnum, then add colinc to colnum until printing can continue at a column beyond the end of the output already on the line.

  • #"line-relative": Output colnum spaces. Then output enough spaces to tab to a column that is a multiple of colinc from the beginning of the line.

  • #"section": This is similar to #"line", but column counting is relative to the beginning of the current section rather than the beginning of the line.

  • #"section-relative": This is similar to #"line-relative", but column counting is relative to the beginning of the current section rather than the beginning of the line.


Chapter 8. The Collection-Extensions Library

Introduction

The various modules in this library contain a few new types and operations which are compatible with the collection types specified in the Dylan Reference Manual , but which are not part of that specification.

It is to be expected that more collection types will appear in time, and they will likely be added to this library. This may also result in reorganizations which could force incompatible changes to the existing modules. We hope to minimize such imcompatibilities and, when forced to them, will include sufficient information to facilitate conversion of existing code.

Collection-extensions exports these modules:

  • self-organizing-list Provides "self-organizing lists". These explicit key collections provide roughly the semantics of hash tables, but use a probabilistic implementation which provides O(n) worst case performance but can provide very fast constant time access in the best case.

  • subseq Provides "subsequences", which represent an aliased reference to some part of an existing sequence. These are analogous to slices (in Ada or Perl) or displaced arrays (in Common Lisp). Subsequences are themselves subclasses of <sequence>, and can therefore be passed any <collection> or <sequence> operation.

  • vector-search Provides a small assortment of specialized operations for searching and modifying <vector>s. These operations are analogous to existing collection operations but provide keywords and efficiency improvements which are meaningful only within the more limited domain.

The Collections-Extensions Library also has some additional modules added by the GwydionDylan Maintainers. These modules are:

  • heap was supposed to implement a priority queue, but because of conflicts with <deque> methods, heap is currently empty.

  • sequence-diff implements the Unix diff utility algorithm

  • Sequence-Utilities provides useful methods on collections, written by Matthias Hölzl.


Module self-organizing-list

The "Self Organizing List" is a poor man's hash table. More precisely, <self-organizing-list> is a subclass of <mutable-explicit-key-collection> and <stretchy-collection> for which addition and retrieval are both linear in the worst case, but which use a probabilistic strategy which yields nearly constant time in the best case.

Because they have a very low overhead, self-organizing lists may provide better peformance than hash tables in cases where references have a high degree of temporal locality. They may also be useful in situations where it is difficult to create a proper hash function.

Instantiate <self-organizing-list>s with

make(<self-organizing-list>, test: test)

Test is expected to be an equality function. In particular, it is expected to satisfy the identity and transitivity requirements as described in the Dylan Reference Manual . If not specified, test defaults to \==.


Module subseq

<Subsequence> is a new subclass of <sequence>. A subsequence represents an aliased reference to some part of an existing sequence. Although they may be created by make (with required keywords source:, start: and end:) on one of the instantiable subclasses, they are more often created by calls of the form

subsequence(sequence, start: 0, end: 3)

where start: and end: are optional keywords which default to the beginning and end, respectively, of the source sequence. No other new operations are defined for subsequences, since all necessary operations are inherited from <sequence>.

Because subsequences are aliased references into other sequences, several properties must be remembered:

  • The contents of a subsequence are undefined after any destructive operation upon the source sequence.

  • Destructive operations upon subsequences may be reflected in the source. The results of reverse! and sort! should be expected to affect the source sequence for vector subsequences.

If the source sequences are instances of <vector> or <string>, then the implementation will use subclasses of <subsequence> which are also subclasses of <vector> or <string>.

Efficiency notes:

  • The implementation tries to insure that subsequences of subsequences can be accessed as efficiently as the original subsequence. (For example, the result of

    subsequence(subsequence(source, start: 1), start: 2)

    would produce a subsequence identical to the one produced by

    subsequence(source, start: 3)
  • Vector subsequences, like all other vectors, implement constant time element access.

  • Non-vector subsequences may take non-constant time to create, but will provide constant-time access to the first element. This should produce the best performance provided some element of the subsequence is accessed at least once.


Module vector-search

The vector-search module provides basic search and replace capabilities upon restricted subsets of <sequence> -- primarily <vector>. Exploiting the known properties of these types yields substantially better performance than can be achieved for sequences in general.


find-first-key[Method]

Find the index of first element of a <vector>

Synopsis

find-first-key (seq, pred?, #key start, end, failure) => ()

Parameters

seqAn instance of <vector>.
pred?An instance of <object>. A <function> that returns #t for a matching condition.
start:An instance of <object>. From which element to start the search Defaults to 0.
end:An instance of <object>. Where to end the search
failure:An instance of <object>. Returned if no match found

Return Values

None.

Description

Find the index of first element (after start but before end) of a vector which satisfies the given predicate. If no matching element is found, return failure. The defaults for start, end and failure are, respectively, 0, size(vector), and #f. This function is like find-key, but accepts start: and end: rather than skip:.


find-last-key[Method]

This is like find-first-key, but goes backward from end.

Synopsis

find-last-key (seq, pred?, #key start, end, failure) => ()

Parameters

seqAn instance of <vector>.
pred?An instance of <object>. A <function> that returns true for a matching condition
start:An instance of <object>. From which element to start the search Defaults to 0.
end:An instance of <object>. Where to end the search
failure:An instance of <object>. Returned if no match found

Return Values

None.

Description

See the description for find-first-key.


Module Sequence-Utilities

Sequence-Utilities, written by Matthias Hölzl, provides common or oft-used operations performed on <sequence>s. The whole module is rather Lispy in flavor, and has the feel of an elegant hack by the way functions use predicate functions to manipulate lists.


Predicate Functions

We start off with a group of generic functions that give boolean responses to type information requests (e.g. "Are you a <list>?").


pair?[Generic]

Check whether this sequence is a pair.

Synopsis

pair? (arg) => (ans)

Parameters

argAn instance of <object>.

Return Values

ansAn instance of <boolean>.

Description

This generic function has two specializers, one that takes instances of <pair> (and subclasses of it) which returns #t and one that takes anything else which returns #f.


null?[Generic]

Check whether this sequence is the empty list.

Synopsis

null? (arg) => (ans)

Parameters

argAn instance of <object>.

Return Values

ansAn instance of <boolean>.

Description

To my mind, this generic function's name is a bit misleading: this returns #t if the instance is an <empty-list>.


list?[Generic]

Check whether this sequence is a list.

Synopsis

list? (arg) => (ans)

Parameters

argAn instance of <object>.

Return Values

ansAn instance of <boolean>.

Description

Returns #t if the instance is a <list>; #f otherwise.


Creational Functions

This section and its subsections describe the functions that create sequences.


Sequence Creational Functions using Sequences

This set of functions provides ways to create sequences from other sequences.


xpair[Function]

Occasionally useful as a value to be passed to a fold or other higher-order procedure.

Synopsis

xpair (list, elt) => (new-list)

Parameters

listAn instance of <list>.
eltAn instance of <object>. The element to add to the list

Return Values

new-listAn instance of <list>.

Description

Xpair puts elt at the head of list.


list*[Function]

Like list, but cons the first elements onto the last element of rest.

Synopsis

list* (#rest rest) => (new-list)

Parameters

restInstances of <object>.

Return Values

new-listAn instance of <list>.

Description

I find description by example best here:

list*(1, 2, 3, 4, 5)    => #(1, 2, 3, 4 . 5)
list*(1, 2, #(3, 4), 5) => #(1, 2, #(3, 4) . 5)
list*(1, 2, 3, #(4, 5)) => #(1, 2, 3, 4, 5)
              

reverse-append[Generic]

Prepend a reversed sequence to another sequence.

Synopsis

reverse-append (reversed-head, tail) => (new-sequence)

Parameters

reversed-headAn instance of <sequence>. A reversed sequence to be prepended before tail.
tailAn instance of <sequence>.

Return Values

new-sequenceAn instance of <sequence>.

Description

reverse-append(#[5, 4, 3, 2, 1], #[6, 7, 8]) => #[1, 2, 3, 4, 5, 6, 7, 8]
	    

Higher-Order Sequence Creational Functions

The next set of functions creates <sequence>s from functions.


tabulate[Function]

Make a sequence by performing a function on the index.

Synopsis

tabulate (length, func, #key type) => (list)

Parameters

lengthAn instance of <integer>.
funcAn instance of <function>. Func takes one argument: the index (an <integer>).
type:An instance of <object>. Defaults to <list>.

Return Values

listAn instance of <mutable-sequence>.

Description

Make a sequence of type type whose i-th element is func(i) for 0 <= i < length. Type must be a subtype of <mutable-sequence>.

For example, I want a vector of the annual worth of an account of 10000 USD earning 10 percent annually. The below code creates that vector:

tabulate(10, method(x) 10000 * exp(x * .1) end, type: <vector>)
              

Or, to create a list of factorials, one could write this:

define function factorial(x :: limited(<integer>, min: 0)) => (y :: <integer>)
  if(x == 0)
    1;
  else
    reduce1(\*, tabulate(x, curry(\+, 1)));
  end if;
end function factorial;

tabulate(6, factorial);
              

Sequence Slicing

This section describes functions that return parts of sequences.


take[Generic]

Returns part of a sequence.

Synopsis

take (collection, k) => (seq)

Parameters

collectionAn instance of <object>.
kAn instance of <integer>. Determines which part of the sequence to return.

Return Values

seqAn instance of <object>.

Description

if k > 0 return a new sequence consisting of the first k elements of collection, otherwise return a new sequence consisting of the last k elements of collection.

For example:

take(#(0, 5, 10, 15, 20, 25, 30), 5)  => #(0, 5, 10, 15, 20, 25)
take(#(0, 3,  6,  9, 12, 15, 18), -3) => #(12, 15, 18)
              

drop[Generic]

Returns part of a sequence.

Synopsis

drop (collection, k) => (seq)

Parameters

collectionAn instance of <object>.
kAn instance of <integer>. Determines which part of the sequence to return.

Return Values

seqAn instance of <object>.

Description

if k > 0 return a new sequence consisting of all but the first k elements of collection, otherwise return a new sequence consisting of all but the last k elements of collection.

For example:

drop(#(0, 5, 10, 15, 20, 25, 30), 5)  => #(25, 30)
drop(#(0, 3,  6,  9, 12, 15, 18), -3) => #(0, 3, 6, 9)
              

last-pair[Function]

Return the last pair in a non-empty list.

Synopsis

last-pair (lst) => (last-pair)

Parameters

lstAn instance of <pair>.

Return Values

last-pairAn instance of <pair>.

Description

I find description by example best here, as well:

last-pair(1, 2, 3, 4, 5)    => #(5)
last-pair(1, 2, 3, #(4, 5)) => #(#(4, 5))
last-pair(1, 2, 3, 4 . 5) => fails
              

The last example fails because last-pair expects the elements of the list to be pairable ... in this case 5 is not.


heads[Function]

A list of all the heads of members of a list.

Synopsis

heads (lists) => (new-list)

Parameters

listsAn instance of <list>. A list of lists

Return Values

new-listAn instance of <list>.

Description

In a list of lists, this function returns a list of the first elements of each of the lists

heads(#(#(1, 5, 10), #(2, 4, 6), #(3, 6, 9))) => #(1, 2, 3)
	      

tails[Function]

A list of all the tails of members of a list.

Synopsis

tails (lists) => (new-list)

Parameters

listsAn instance of <list>. A list of lists

Return Values

new-listAn instance of <list>.

Description

In a list of lists, this function returns a list of the all but first elements of each of the lists

tails(#(#(1, 5, 10), #(2, 4, 6), #(3, 6, 9))) => #(#(5, 10), #(4, 6), #(6, 9))
	      

Finding Sequence Elements

These functions inspect elements of a sequence and return information on them.


satisfies[Method]

Find an element, return its index

Synopsis

satisfies (pred, seq, #key failure) => (index)

Parameters

predAn instance of <function>. The test function to find the element.
seqAn instance of <sequence>.
failure:An instance of <object>. The value returned if a matching element is not found. Defaults to #f.

Return Values

indexAn instance of <object>. The index of the found element.

Description

Locates an element in seq that returns a value (i.e. not #f) from pred, and returns the index. Note, the index is not necessarily an integer ... <table> can use non-integer indices.


index[Method]

Find an element, return its index

Synopsis

index (elt, seq, #key test, failure) => (index)

Parameters

eltAn instance of <object>. The sought element.
seqAn instance of <sequence>.
test:An instance of <object>. The test function to find the element. Defaults to \=.
failure:An instance of <object>. The value returned if a matching element is not found. Defaults to #f.

Return Values

indexAn instance of <object>. The index of the found element.

Description

Very much like the satisfies function. This allows the user to specify the element sought, and assumes the test is \= by default.


find[Method]

Find an element

Synopsis

find (pred, seq, #key failure) => (obj)

Parameters

predAn instance of <function>.
seqAn instance of <sequence>.
failure:An instance of <object>. The value returned if a matching element is not found. Defaults to #f.

Return Values

objAn instance of <object>. The found element.

Description

The find function locates and returns an object in a sequence when that object matches the predicate function passed in as pred.


find-tail[Method]

Gives the rest of a list from a found element.

Synopsis

find-tail (pred, seq, #key failure) => (result)

Parameters

predAn instance of <function>.
seqAn instance of <sequence>.
failure:An instance of <object>. The value returned if a matching element is not found. Defaults to #f.

Return Values

resultAn instance of <object>. The found list.

Description

The find-tail function locates an object in a sequence when that object matches the predicate function passed in as pred. When that element is found, it, and the rest of the sequence, is returned as the result.


precedes?[Method]

Verifies that one element comes before another in a sequence.

Synopsis

precedes? (elt-1, elt-2, seq, #key test, not-found) => (precedes?)

Parameters

elt-1An instance of <object>. The preceding element.
elt-2An instance of <object>. The following element.
seqAn instance of <sequence>.
test:An instance of <object>. The test function to find the elements. Defaults to \=.
not-found:An instance of <object>. The value returned if either element not found. Defaults to #f.

Return Values

precedes?An instance of <boolean>.

Description

Ensures elt-2 follows elt-1, in seq, if so, returns #t.


Mapping and Reducing Functions

These higher-order functions require an understanding of the mapping and reducing functions found in the Dylan Reference Manual described on pages 327 and on. What they do is to perform an operation on a sequence to obtain a result.


foldr[Function]

Rebuilds a list by applying a function over it.

Synopsis

foldr (cons, nil, lst) => (result)

Parameters

consAn instance of <function>. A function that takes two arguments and returns a <pair>.
nilAn instance of <object>. Value returned if the list is empty (in most cases, this should be #()).
lstAn instance of <list>.

Return Values

resultAn instance of <list>.

Description

This function rebuilds a list by recursively applying a function over the list. For example, to copy a list, one would write:

foldr(pair, #(), #(1, 2, 3, 4, 5)) => #(1, 2, 3, 4, 5)
	    

Exercise: what is the result when you replace pair with list?


foldl[Function]

Rebuilds a list by applying a function over it.

Synopsis

foldl (cons, nil, lst) => (result)

Parameters

consAn instance of <function>. A function that takes two arguments and returns a <pair>.
nilAn instance of <object>. Value returned if the list is empty (in most cases, this should be #()).
lstAn instance of <list>.

Return Values

resultAn instance of <list>.

Description

Foldr in reverse. This function rebuilds a list by recursively applying a function over the list. For example:

foldl(method(x, y) pair(factorial(x), y) end, #f, #(1, 2, 3, 4, 5))
 => #(120, 24, 6, 2, 1 . #f)
	    

Note: the ugly dotted pair at the end is what occurs when nil is not #().


concatenate-map[Method]

Concatenates sequences then maps a function over them.

Synopsis

concatenate-map (func, seq, #rest seqs) => (new-sequence)

Parameters

funcAn instance of <function>.
seqAn instance of <sequence>.
seqsInstances of <object>.

Return Values

new-sequenceAn instance of <sequence>.

Description

Concatenates seq and all members of seqs together and maps func over the resulting list. The order of function applications is unspecified.


choose-map[Method]

Maps a function over a sequence, then chooses selected elements.

Synopsis

choose-map (pred, func, seq, #rest seqs) => (new-sequence)

Parameters

predAn instance of <function>.
funcAn instance of <function>.
seqAn instance of <sequence>.
seqsInstances of <object>.

Return Values

new-sequenceAn instance of <sequence>.

Description

Map func across lst and save up all the results that satisfy pred.


pair-do[Function]

Like do, except that it takes multiple argument lists

Synopsis

pair-do (func, lst, #rest lists) => (false)

Parameters

funcAn instance of <function>. A function that takes 1 or more instances of <list> as arguments.
lstAn instance of <list>. A list of values that will be used as the first argument to func.
listsInstances of <list>. Each argument should be a <list>.

Return Values

falseAn instance of <boolean>. #f

Description

This function takes a n-ary function, and n instances of <list> as arguments. It then applies func to all of the lists, and then recursively applies func to all of the sublists of the lists. Contrast this with the do function, which is applied to each set of elements of the arguments rather to sublists.


pair-foldl[Function]

This function is like foldl, but works on sublists.

Synopsis

pair-foldl (cons, nil, lst) => (obj)

Parameters

consAn instance of <function>. This argument is a function that can take two objects as arguments and returns a new object.
nilAn instance of <object>.
lstAn instance of <list>.

Return Values

objAn instance of <object>.

Description

This function is similar to foldl, except that it operates on sublists instead of elements. That is, its recursion scheme is as follows: if lst is #(e1, e2, ..., en), then this function returns

cons(#(en), cons(..., cons(#(e2,...en), cons(#(e1,...,en), nil) ...)))


pair-foldr[Function]

This function is like foldr, but works on sublists.

Synopsis

pair-foldr (cons, nil, lst) => (obj)

Parameters

consAn instance of <function>. This argument is a function that can take two objects as arguments and returns a new object.
nilAn instance of <object>.
lstAn instance of <list>.

Return Values

objAn instance of <object>.

Description

This function is similar to foldr, except that it operates on sublists instead of elements. That is, its recursion scheme is as follows: if lst is #(e1, e2, ..., en), then this function returns

cons(#(e1, ..., en), cons(#(e2,...en), cons(..., cons(#(en), nil) ...)))


partition[Function]

Returns two lists: one that satisfies a predicate, and one that doesn't.

Synopsis

partition (pred, seq) => (winners, losers)

Parameters

predAn instance of <function>.
seqAn instance of <sequence>.

Return Values

winnersAn instance of <list>. The list of elements that satisfy the predicate.
losersAn instance of <list>. The list of elements that do not.

Description

This is very much like choose found in the Dylan Reference Manual (page 333), except this function also returns the elements that did not match the predicate.


unfold[Function]

This function is dual to fold; instead of taking some functions and a list and producing a value, it takes a value and some functions and produces a list.

Synopsis

unfold (pred, f, g, seed) => (new-list)

Parameters

predAn instance of <function>. This function takes a seed value and returns #t to terminate the sequence of recursive calls building the list.
fAn instance of <function>. This function takes a seed value and produces a list element.
gAn instance of <function>. This function takes a seed value and returns a new seed value.
seedAn instance of <object>. The initial seed value.

Return Values

new-listAn instance of <list>.

Description

This function will return #() if pred(seed) is true. Otherwise it builds a pair of the form pair(f(seed), unfold(pred, f, g, g(seed) )) .

Thus, this function will always return a proper list, if it terminates at all.


unfold/tail[Function]

This function is similar to unfold, except that it can also be used to build an improper list.

Synopsis

unfold/tail (pred, f, g, e, seed) => (new-list)

Parameters

predAn instance of <function>. This function takes a seed value and returns #t to terminate the sequence of recursive calls building the list.
fAn instance of <function>. This function takes a seed value and produces a list element.
gAn instance of <function>. This function takes a seed value and returns a new seed value.
eAn instance of <function>. When pred returns #t this function is called on the seed to return the value of the tail of the last pair of the list.
seedAn instance of <object>. The initial seed value.

Return Values

new-listAn instance of <list>.

Description

This function will return e(seed) if pred(seed) is true. Otherwise it builds a pair of the form pair(f(seed), unfold(pred, f, g, g(seed) )) .

If e always returns #() then unfold/tail has the same behavior as unfold.


Associative Lists

Those familiar with Lisp will feel at home here. Associative lists are <list>s that contain <pair>s of entries (in a #(key, value) format). Much like <table>s, one make look up the key to obtain the value information.


assoc[Function]

Looks up a value given a key

Synopsis

assoc (elt, seq, #key key, test) => (found)

Parameters

eltAn instance of <object>. The key element to find the value element
seqAn instance of <sequence>.
key:An instance of <object>. The function used to obtain the key element in the associative list. Defaults to head.
test:An instance of <object>. The function used to compare. Defaults to \=.

Return Values

foundAn instance of <object>. The value element from the found key.

Description

Find the tuple associated with key in the association sequence seq.


apair[Function]

Adds an association to a sequence.

Synopsis

apair (key, datum, aseq, #key cons, add) => (new-aseq)

Parameters

keyAn instance of <object>. The key element of the association.
datumAn instance of <object>. The value element of the association.
aseqAn instance of <sequence>.
cons:An instance of <object>. The function used to create the association from the key and datum parameters. Defaults to pair.
add:An instance of <object>. The function used to add the association onto the sequence. Defaults to xpair.

Return Values

new-aseqAn instance of <object>. The new associative list.

Description

Cons a new pair #(key, datum) on the head of aseq.


alist-copy[Function]

Copies an associative list.

Synopsis

alist-copy (alist, #key key, datum, cons) => (new-aseq)

Parameters

alistAn instance of <sequence>.
key:An instance of <object>. The function used to obtain the key element from the association. Defaults to head.
datum:An instance of <object>. The function used to obtain the value element. Defaults to tail.
cons:An instance of <object>. The function used to create the association from the key and datum parameters. Defaults to pair.

Return Values

new-aseqAn instance of <object>. The new associative list.

Description

Copy an "associative list", actually any sequence that can act like an associative list.


alist-delete[Function]

Deletes associations from the associative list.

Synopsis

alist-delete (elt, alist, #key key, test) => (new-alist)

Parameters

eltAn instance of <object>. The key element of the association to be removed.
alistAn instance of <sequence>.
key:An instance of <object>. The function used to obtain the key element from the association. Defaults to head.
test:An instance of <object>. The function used to compare keys. Defaults to \=.

Return Values

new-alistAn instance of <object>. The new associative list.

Description

Delete all members keyed by elt from alist.


Functions Not Yet Described

The following bindings (all of which are functions) have not yet been described. I will add these descriptions as time and understanding permit. For now, you must rely on the best documentation available ... the source code in src/common/coll-ext/sequence-utils.dylan.

  • reduce-l

  • reduce-r


Chapter 9. The table-extensions Library

The table-extensions Module

This library contains a number of useful additional table classes, and a number of functions that could be useful in constructing your own table classes.


<case-insensitive-string-table> [ sealed instantiable Class]

Implements a <table> class, keyed by strings keyed without regard for case.

Superclasses

<value-table>

Initialization Keywords

None.

Description

<case-insensitive-string-table> implements a <table> class whose keys are instances of <string> . However, instead of using \= for the equivalence relation, strings which are the same modulo case are considered equivalent.

Note that the case-insensitivity is true in general only for English strings -- non-English characters have their case "normalized" by subtracting the difference in integer code for the character 'a' and 'A'. This works only for ASCII and Unicode, and only for English.


<equal-table> [ sealed instantiable Class]

Implements a class which compares keys using \= .

Superclasses

<table>

Initialization Keywords

None.

Description

<equal-table> implements a <table> class whose keys are compared with \= rather than \== . So for example, two instances of list that don't have object identity, but did contain references to the same object, would be considered equivalent keys by <equal-table> .


<hash-state> [Class]

The type of hash states.

Superclasses

None.

Initialization Keywords

None.

Description

<hash-state> is the type of the hash state returned as the second value of hash functions. For example, $permanent-hash-state is of type <hash-state> .


<string-table> [ sealed instantiable Class]

A <table> class keyed by strings.

Superclasses

<value-table>

Initialization Keywords

None.

Description

This class implements a <table> class that is keyed by \= equal <string> instances.


<value-table>[ open abstract Class]

Intended as the abstract superclass of user-defined tables.

Superclasses

<table>

Initialization Keywords

None.

Description

This class is intended to be an abstract superclass of <table> classes that have user-defined key comparison and hash functions. (NB: The hash functions cannot involve physical addresses.)


case-insensitive-equal [Generic]

Tests whether two objects (usually strings) are the same modulo case.

Synopsis

case-insensitive-equal ( object-1 , object-2 ) => ( answer )

Parameters

object-1 An instance of <object> .
object-2 An instance of <object> .

Return Values

answer An instance of <boolean> .

Description

Tests whether two objects have the same string value modulo case. Comparisons to non- <string> or <character> instances return #f.


case-insensitive-equal [Method]

Least-specific method testing whether two objects are the same modulo case.

Synopsis

case-insensitive-equal ( object-1 , object-2 ) => ( answer )

Parameters

object-1 An instance of <object> .
object-2 An instance of <object> .

Return Values

answer An instance of <boolean> .

Description

Since at least one of the arguments is not a <character> or <string> , this method always returns #f.


case-insensitive-equal [Method]

Method testing whether two characters are the same modulo case.

Synopsis

case-insensitive-equal ( object-1 , object-2 ) => ( answer )

Parameters

object-1 An instance of <character> .
object-2 An instance of <character> .

Return Values

answer An instance of <boolean> .

Description

This method returns #t if either the two arguments are the same character, or if they are alphabetic characters that are the same character modulo case. (This only works for English characters in general.)


case-insensitive-equal [Method]

Method testing whether two strings are the same modulo case.

Synopsis

case-insensitive-equal ( object-1 , object-2 ) => ( answer )

Parameters

object-1 An instance of <string> .
object-2 An instance of <string> .

Return Values

answer An instance of <boolean> .

Description

This method returns #t if the two arguments are the same size, and each component character returns #t with a case-insensitive-equal.


case-insensitive-string-hash[Function]

The default hash function for case-insensitive strings.

Synopsis

case-insensitive-string-hash ( s , initial-state ) => ( id , hash-state )

Parameters

s An instance of <string> .
initial-state An instance of <hash-state> .

Return Values

id An instance of <integer> .
hash-state An instance of <hash-state> .

Description

This is a convenient hash function for case-insensitive strings. It is returned as the table-protocol method's second value for <case-insensitive-string-table> .


collection-hash [Function]

A function for building hash functions that test collection equivalence.

Synopsis

collection-hash ( key-hash , element-hash , col , initial-state , #key ordered ) => ( id , state )

Parameters

key-hash An instance of <function> . Computes hash ids for the keys. It takes an object and a <hash-state> as an argument, and returns a hash id and a hash state.
element-hash An instance of <function> . Computes hash ids for the elements. It takes an object and a <hash-state> as an argument, and returns a hash id and a hash state.
col An instance of <collection> .
initial-state An instance of <hash-state> .
ordered :An instance of <boolean> . Whether or not to do an ordered merge of the key/element hash codes. The default is #f.

Return Values

id An instance of <integer> . The hash id.
state An instance of <hash-state> .

Description

Two collections will yield the same hash id, if each of their keys/element pairs hash to the same value. It's safe to set the ordered: keyword argument to #t only if the collection has a natural iteration order.


equal-hash [Generic]

Computes hash ids for objects such that two objects that are \= equal have the same hash id.

Synopsis

equal-hash ( thing , state ) => ( id , state )

Parameters

thing An instance of <object> .
state An instance of <hash-state> .

Return Values

id An instance of <integer> .
state An instance of <hash-state> .

Description

Methods on equal-hash should return hash ids such that the id for two \= equal objects are the same.

There is a default method is defined on all instances of <object>, and it returns a valid hash id in all cases. However, performance *will* suck horribly (algorithmically, even) if you don't define better methods for your own objects that will live in <equal-table> instances.

Good methods for equal-hash are defined for <integer>, <float>, <symbol>, <type>, <function>, <boolean>, <condition>, and <collection>. (Note that <collection> is a supertype of <string>.)


remove-all-keys! [Function]

Remove all keys from a table.

Synopsis

remove-all-keys! ( coll ) => ( coll )

Parameters

coll An instance of <mutable-explicit-key-collection> .

Return Values

coll An instance of <mutable-explicit-key-collection> .

Description

This function iterates through all the keys and calls remove-key! on each one.


sequence-hash [Function]

Like collection-hash , only a more efficient version just for sequences.

Synopsis

sequence-hash ( element-hash , seq , initial-state ) => ( id , state)

Parameters

element-hash An instance of <function> . Computes hash ids for the elements. It takes an object and a <hash-state> as an argument, and returns a hash id and a hash state.
seq An instance of <sequence> .
initial-state An instance of <hash-state> .

Return Values

id An instance of <integer> .
stateAn instance of <hash-state>.

Description

This is similar to an equal-hash, except that it hashes things with ordered: #t and ignores the sequence keys. USE WITH CAUTION: This isn't a proper equal-hash because two collections of different types but identical key/element pairs won't generate the same hash id, even though the two collections are \=.


string-hash [Function]

A convenient function for hashing strings

Synopsis

string-hash ( s , initial-state ) => ( id , state )

Parameters

s An instance of <string> .
initial-state An instance of <hash-state> .

Return Values

id An instance of <integer> .
state An instance of <hash-state> .

Description

A convenient method for hashing strings. Used by <string-table> .


value-hash [Generic]

Computes hash ids for objects such that two objects that are \= equal have the same hash id.

Synopsis

value-hash ( thing , state ) => ( id , state )

Parameters

thing An instance of <object> .
state An instance of <hash-state> .

Return Values

id An instance of <integer> .
state An instance of <hash-state> .

Description

Methods on equal-hash should return hash ids such that the id for two \= equal objects are the same.

There is a default method is defined on all instances of <object>, and it returns a valid hash id in all cases. However, performance *will* suck horribly (algorithmically, even) if you don't define better methods for your own objects that will live in <equal-table> instances.

Good methods for equal-hash are defined for <integer>, <float>, <symbol>, <type>, <function>, <boolean>, <condition>, and <collection>. (Note that <collection> is a supertype of <string>.)


Chapter 10. The string-extensions Library

Module character-type

This module contains a set of methods for testing various properties of <character> this will work 100% correctly only with ASCII English characters. Fixing this so it handles Unicode better would be a good way of covering yourself with glory, hint hint.


alphabetic?[Function]

Returns #t if the character is in [a-zA-Z].

Synopsis

alphabetic? (character) => (answer)

Parameters

characterAn instance of <character>

Returns

answerAn instance of <boolean>

Description

Returns #t if the character is alphabetic, #f otherwise.

digit?[Function]

Returns #t if the character is a numeric digit [0-9].

Synopsis

digit? (character) => (answer)

Parameters

characterAn instance of <character>

Returns

answerAn instance of <boolean>

Description

Returns #t if the character is a digit, #f otherwise.

alphanumeric?[Function]

Returns #t if the character is alphabetic or a digit.

Synopsis

alphanumeric? (character) => (answer)

Parameters

characterAn instance of <character>

Returns

answerAn instance of <boolean>

Description

Returns #t if the character is alphanumeric, #f otherwise.

whitespace?[Function]

Returns #t if the character is whitespace.

Synopsis

whitespace? (character) => (answer)

Parameters

characterAn instance of <character>

Returns

answerAn instance of <boolean>

Description

Returns #t if the character is whitespace (space, tab, linefeed, or newline), #f otherwise.

lowercase?[Function]

Returns #t if the character is in [a-z].

Synopsis

lowercase? (character) => (answer)

Parameters

characterAn instance of <character>

Returns

answerAn instance of <boolean>

Description

Returns #t if the character is lowercase (in [a-z]), #f otherwise.

hex-digit?[Function]

Returns #t if the character is a hexadecimal digit.

Synopsis

hex-digit? (character) => (answer)

Parameters

characterAn instance of <character>

Returns

answerAn instance of <boolean>

Description

Returns #t if the character is a hexadecimal digit; that is, if it is in [0-9], [a-f] or [A-F], #f otherwise.

graphic?[Function]

Returns #t if the character is a graphic character.

Synopsis

graphic? (character) => (answer)

Parameters

characterAn instance of <character>

Returns

answerAn instance of <boolean>

Description

Returns #t if the character is a printing, non-whitespace character, #f otherwise.

printable?[Function]

Returns #t if the character is printable.

Synopsis

printable? (character) => (answer)

Parameters

characterAn instance of <character>

Returns

answerAn instance of <boolean>

Description

Returns #t if the character is a printing character, #f otherwise.

punctuation?[Function]

Returns #t if the character is punctuation.

Synopsis

punctuation? (character) => (answer)

Parameters

characterAn instance of <character>

Returns

answerAn instance of <boolean>

Description

Returns #t if the character is a graphic, non-alphanumeric character, #f otherwise.

control?[Function]

Returns #t if the character is not printable.

Synopsis

control? (character) => (answer)

Parameters

characterAn instance of <character>

Returns

answerAn instance of <boolean>

Description

Returns #t if the character is a control character, #f otherwise.

byte-character?[Function]

Returns #t if the character is an ASCII character. Could be flaky.

Synopsis

byte-character? (character) => (answer)

Parameters

characterAn instance of <character>

Returns

answerAn instance of <boolean>

Description

Returns #t if the character is a byte-character (which is if the integer value of the character returns less than 256. I don't know enough about Unicode and character set encodings to say what this means), #f otherwise.

uppercase?[Function]

Returns #t if the character is uppercase.

Synopsis

uppercase? (character) => (answer)

Parameters

characterAn instance of <character>

Returns

answerAn instance of <boolean>

Description

Returns #t if the character is in [A-Z], #f otherwise.

The string-conversions Module

This module contains some handy functions to convert numbers to strings and vice-versa, as well some <character> to <string> conversions. [Note: It might be a good idea to try making string-to-integer and integer-to-string methods on as, which is the usual generic for type coercions. Ask about this on the GD mailing list.]


as[Function]

Convert a character to a string.

Synopsis

as (class, character) => (string)

Parameters

classAn instance of singleton(<string>).
characterAn instance of <character>.

Return Values

stringAn instance of <string>.

Description

as(<string>, character) returns a fresh instance of <string> of size 1, whose only element is the character.


digit-to-integer[Function]

Convert a character to the integer it denotes.

Synopsis

digit-to-integer (character) => (integer)

Parameters

characterAn instance of <character>. An error is signalled character it is not alphanumeric.

Return Values

integerAn instance of <integer>. Between 0 and 35, inclusive.

Description

Digit-to-integer converts an alphanumeric character to an integer. '0' through '9' convert to 0 to 9, and 'a' through 'z' convert to 10 to 35. An error is signalled if the character is not in this range.


integer-to-digit[Function]

Convert an integer to the corresponding digit.

Synopsis

integer-to-digit (digit, #key base, uppercase) => (digit)

Parameters

digitAn instance of <integer>.
base:An instance of <integer>. Between 2 and 35, inclusive, representing the radix of the digit to return. The default base is 10.
uppercase:An instance of <boolean>. For #t returns uppercase letters for digits greater than 10, and lowercase for #f. The default is #f.

Return Values

digitAn instance of <character>. The returned digit is an alphanumeric character.

Description

Integer-to-digit converts an integer to the corresponding digit in the specified base. If the integer is outside the range a single digit in the specified base can represent, an error is signalled. Digits for values of 10 or higher are represented with the letters 'a' through 'z', with 'a' for 10 and 'z' for 35.


integer-to-string[Function]

Converts an integer to a string value.

Synopsis

integer-to-string (num, #key base, uppercase) => (number)

Parameters

numAn instance of <integer>.
base:An instance of <integer>. Base: should be between 2 and 36, inclusive, and is the radix of the string representation. An error will be signalled for radixes not in this range. Defaults to 10.
uppercase:An instance of <boolean>. If it is #t, then uppercase letters will be used to represent digits higher than 9, and lowercase will be used if #f.

Return Values

numberAn instance of <string>.

Description

Integer-to-string converts an integer to a string. String representations for radixes above 10 use the letters 'a' through 'z' for the digits from 10 to 35. So hexadecimal numbers would use [0-9] and [a-f], and base 20 would use [0-9] and [a-j], and base 36 would use all the alphanumeric characters.


string-to-integer[Function]

Read a sequence of characters as an integer.

Synopsis

string-to-integer (string, #key base) => (integer)

Parameters

stringAn instance of <sequence>. Any <sequence> of <character> objects are acceptable. This is typically but not necessarily a <string>.
base:An instance of <integer>. Between 2 and 36, inclusive, denoting the base to read integers in. An error is signalled if base is not in this range. Defaults to 10.

Return Values

integerAn instance of <integer>.

Description

String-to-integer converts a sequence of <character> objects to an integer. The characters are the digits of the string representation, and must lie between '0' and 'z', with a maximum depending on the base. For example, octal (base 8) digits must be in [0-7], decimal digits must be in [0-9], and hexadecimal digits must be in [0-9] or [a-f]. An error is signalled if this constraint is violated. (Start negative integers with a '-', so "-36" would become -36.)


The string-hacking Module

This module contains some random, possibly-useful functions to munge strings.


The substring-search Module

This module contains some functions to do fast Boyer-Moore searching on strings.


Chapter 11. The Regular-Expressions Library

The Regular-expressions library exports the Regular-expressions module, which contains various functions that deal with regular expressions (abbreviated to "regexps"). The module is based on Perl (version 4), and has the same semantics unless otherwise noted. The syntax for Perl-style regular expressions can be found in Perl 5 Desktop Reference . There are some differences in the way String-extensions handles regular expressions. The biggest difference is that regular expressions in Dylan are case insensitive by default. Also, when given an unparsable regexp, String-extensions will produce undefined behavior while Perl would give an error message.

A regular expression that is grammatically correct may still be illegal if it contains an infinitely quantified sub-regexp that may match the empty string. That is, if R is a regexp that can match the empty string, then any regexp containing R*, R+, and R{n,} is illegal. In this case, the Regular-expressions library will signal an <illegal-regexp> error when the regexp is parsed. Note: Perl also has this restriction, although it isn't mentioned in Perl 5 Desktop Reference .

In previous versions of the regular-expressions library, each basic function had a companion function that would pre-compute some information needed to use the regular expression. By using the companion function, one could avoid recomputing the same information. In the present version, the regular-expressions library caches this information, so the companion functions are no longer necessary and should be considered obsolete. However, they have been kept for backwards compatibility.

Companion functions differ in details, but they all essentially return curried versions of their corresponding basic function. For example, the following two pieces of code yield the same result:

regexp-position("This is a string", "is");
    

or

let is-finder = make-regexp-positioner("is");
is-finder("This is a string");
    

Both pieces of code should have roughly the same performance, even if the code is inside a loop. The first is the preferred method of using regexps.


Regular-expressions Module

Make-Foo vs. Foo Functions

There are quite a few make-fooer functions hanging around. Now that regexp-position does caching, these are basically useless, but we've kept them around for backwards compatibility. Unfortunately, internally most of the functions are implemented in terms of make-regexp-positioner. To minimize the amount of rewriting, I've liberally applied seals and inline declarations so that make-regexp-positioner won't clobber all type information. The downside, of course, is that everything's sealed, but hey, no one ever subclassed [ed: specialized?] regexp-position anyway.


Caching

Parsing a regexp is not cheap, so we cache the parsed regexps and only parse a string if we haven't seen it before. Because in practice almost all regexp strings are string literals, we're free to choose \== or \= depending on whatever's fastest. However, because a string is parsed differently depending on whether the search is case sensitive or not, we also have to keep track of that information as well. (The case dependent parse boils down to the parse creating a <character-set>, which must be either case sensitive or case insensitive).

Note: Currently, only regexp-position uses this cache, because the other functions are still using make-regexp-positioner. With caching, that make-regexp-whatever stuff should probably go.


Exported Names


regexp-position[Function]

The index of a regexp in a string

Synopsis

regexp-position (big, regexp, #key start, end, case-sensitive) => (regexp-start, #rest marks)

Parameters

bigAn instance of <string>. The string to parse.
regexpAn instance of <string>.
start:An instance of <object>. Where to start parsing the string. Defaults to 0.
end:An instance of <object>. If defined, where to stop parsing the string. Defaults to #f.
case-sensitive:An instance of <object>. Match case in regexp while parsing. Defaults to #f.

Return Values

regexp-startAn instance of false-or(<integer>). If defined, the index of the match.
marksInstances of false-or(<integer>). The position of the end of the matche in the string (see below).

Description

Find the position of a regular expression inside a string. If the regexp is not found, return #f, otherwise return a variable number of marks.

This function returns the index of the start of the regular expression in the big-string, or #f if the regular expression is not found. As a second value, it returns the index of the end of the regular expression in the big-string (assuming it was found; otherwise there is no second value). These values are called marks, and they come in pairs, a start-mark and an end-mark. If there are groups in the regular expression, regexp-position will return an additional pair of marks (a start and an end) for each group. If the group is matched, these marks will be integers; if the group is not matched, the marks will be #f. So

regexp-position("This is a string", "is");
	    

returns values(2, 4) and

regexp-position("This is a string", "(is)(.*)ing");
	    

returns values(2, 16, 2, 4, 4, 13), while

regexp-position("This is a string", "(not found)(.*)ing");
	    

returns #f. Marks are always given relative to the start of big-string, not relative to the start: keyword.


regexp-replace[Function]

Replace information in a string.

Synopsis

regexp-replace (input, regexp, new-substring, #key count, case-sensitive, start, end) => (changed-string)

Parameters

inputAn instance of <string>. The string to parse and replace pieces of.
regexpAn instance of <string>.
new-substringAn instance of <string>. The replacement string.
count:An instance of <object>. If supplied, number of substitutions to make. Defaults to #f.
case-sensitive:An instance of <object>. Match case in regexp while parsing. Defaults to #f.
start:An instance of <object>. Where to start parsing the string. Defaults to 0.
end:An instance of <object>. If defined, where to stop parsing the string. Defaults to #f.

Return Values

changed-stringAn instance of <string>.

Description

This replaces all occurrences of regexp in input with new-substring. If count: is specified, it replaces only the first count occurrences of regexp. (This is different from Perl, which replaces only the first occurrence unless /g is specified) New-substring can contain backreferences to the regexp. For instance,

regexp-replace("The rain in Spain and some other text",
               "the (.*) in (\\w*\\b)", "\\2 has its \\1")
	    

returns "Spain has its rain and some other text". If the subgroup referred to by the backreference was not matched, the reference is interpreted as the null string. For instance,

regexp-replace("Hi there", "Hi there(, Bert)?",
               "What do you think\\1?")
	    

returns "What do you think?" because ", Bert" wasn't found.


translate[Method]

Equivalent to Perl's tr. Does a character by character translation.

Synopsis

translate (input, from-set, to-set, #key delete, start, end) => (output)

Parameters

inputAn instance of <string>. The string to translate.
from-setAn instance of <string>. String specification of a character set.
to-setAn instance of <string>. Another character set.
delete:An instance of <object>. If #t, any characters in the from-string that don't have matching characters in the to-string are deleted. Defaults to #f.
start:An instance of <object>. Where to start parsing the string. Defaults to 0.
end:An instance of <object>. If defined, where to stop parsing the string. Defaults to #f.

Return Values

outputAn instance of <string>.

Description

This is equivalent to Perl's tr/// construct. From-string is a string specification of a character set, and to-string is another character set. Translate converts input character by character, according to the sets. For instance,

translate("any string", "a-z", "A-Z")
	    

will convert "any string" to all uppercase: "ANY STRING".

Like Perl, character ranges are not allowed to be "backwards". The following is not legal:

translate("any string", "a-z", "z-a")
	    

(This restriction may be removed in future releases) Unlike Perl's tr///, translate doesn't return the number of characters translated.

If delete: is #t, any characters in the from-string that don't have matching characters in the to-string are deleted. The following will remove all vowels from a string and convert periods to commas:

translate("any string", ".aeiou", ",", delete: #t)
	    

Delete: is #f by default. If delete: is #f and there aren't enough characters in the to-string, the last character in the to-string is reused as many times as necessary. The following converts several punctuation characters into spaces:

translate("any string", ",./:;[]{}()", " ");
	    

Start: and end: indicate which part of input to translate. They default to the entire string.

Note: Translate is always case sensitive.


split[Function]

Breaks up a string along boundary characters.

Synopsis

split (pattern, input, #key count, remove-empty-items, start, end) => (#rest whole-bunch-of-strings)

Parameters

patternAn instance of <string>. The regexp to split on.
inputAn instance of <string>. The string to parse and replace pieces of.
count:An instance of <object>. If supplied, maximum number of strings to return. Defaults to #f.
remove-empty-items:An instance of <object>. Magically skips empty items when #t. Defaults to #t.
start:An instance of <object>. Where to start parsing the string. Defaults to 0.
end:An instance of <object>. If defined, where to stop parsing the string. Defaults to #f.

Return Values

whole-bunch-of-stringsInstances of <string>.

Description

This is like Perl's split function. It searches input from occurrences of pattern, and returns substrings that were delimited by that regexp. For instance,

split("-", "long-dylan-identifier")
	    

returns values("long", "dylan", "identifier"). Note that what matched the regexp is left out. Remove-empty-items, which defaults to true, magically skips over empty items, so that

split("-", "long--with--multiple-dashes")
	    

returns values("long", "with", "multiple", "dashes"). Count is the maximum number of strings to return. If there are n strings and count is specified, the first count - 1 strings are returned as usual, and the countth string is the remainder, unsplit. So

split("-", "really-long-dylan-identifier", count: 3)
	    

returns values("really", "long", "dylan-identifier"). If remove-empty-items is #t, empty items aren't counted.

Start: and end: indicate what part of input should be looked at for delimiters. They default to the entire string. For instance,

split("-", "really-long-dylan-identifier", start: 8)
	    

returns values("really-long", "dylan", "identifier").

Note: Unlike Perl, empty regular expressions are never legal regular expressions, so there is no way to split a string into a bunch of single character strings. Of course, in Dylan this is not a useful thing to do (as one can get each character of the string by iteration or by indexing), so this is not really a problem.


join[Function]

Does the opposite of split.

Synopsis

join (delimiter, #rest strings) => (big-string)

Parameters

delimiterAn instance of <string>.
stringsInstances of <object>.

Return Values

big-stringAn instance of <string>.

Description

This is like Perl's join function. This is not really any more efficient than concatenate-as, but it's more convenient.

join(":", word1, word2, word3)
	    

is equivalent to

concatenate(word1, ":", word2, ":", word3)
	    

(and no more efficient).


<illegal-regexp>[sealed Class]

Signaled when a function receives an illegal regular expression.

Superclasses

<error>

Initialization Keywords

regexp:An instance of <string>. The regexp that caused the error

Description

Signaled when a function receives an illegal regular expression.


Deprecated Functions

These functions still work, but are deprecated. Use the foo functions (described above) instead of these make-foo functions.


make-regexp-positioner[Function]

[Deprecated] Creates a function that finds the index of a regexp in a string.

Synopsis

make-regexp-positioner (regexp, #key byte-character-only, needs-marks, maximum-compile, case-sensitive) => (regexp-positioner)

Parameters

regexpAn instance of <string>.
byte-character-only:An instance of <object>. Ignored. Defaults to #f.
needs-marks:An instance of <object>. Ignored. Defaults to #f.
maximum-compile:An instance of <object>. Ignored. Defaults to #f.
case-sensitive:An instance of <object>. Match case in regexp while parsing. Defaults to #f.

Return Values

regexp-positionerAn instance of <function>. The function to execute a match on a string.

Description

Once upon a time, this was how you interfaced to the NFA stuff (maximum-compile: #t). That's gone. Now it's just here for backwards compatibility. All keywords except case-sensitive are now ignored.


make-regexp-replacer[Function]

[Deprecated] Creates a function that replaces information in a string.

Synopsis

make-regexp-replacer (regexp, #key replace-with, case-sensitive) => (replacer)

Parameters

regexpAn instance of <string>.
replace-with:An instance of <object>. The replacement string.
case-sensitive:An instance of <object>. Match case in regexp while parsing. Defaults to #f.

Return Values

replacerAn instance of <function>. The function that does the replacement.

Description

This returns an anonymous replacer function that is either

method (big-string, #key count, start, end)
		

or

method (big-string, replace-string, #key count, start, end)
		

The first form is returned if the replace-with: keyword isn't supplied, otherwise the second form is returned.


make-translator[Method]

[Deprecated] Creates a function that translates a string.

Synopsis

make-translator (from-set, to-set, #key delete) => (translator)

Parameters

from-setAn instance of <string>. String specification of a character set.
to-setAn instance of <string>. Another character set.
delete:An instance of <object>. If #t, delete from-set characters not in to-set. Defaults to #f.

Return Values

translatorAn instance of <function>. The function that does the translation.

Description

This returns an anonymous translation function.


make-splitter[Function]

[Deprecated] Creates a function that splits a string.

Synopsis

make-splitter (pattern) => (splitter)

Parameters

patternAn instance of <string>. The regexp to split on.

Return Values

splitterAn instance of <function>. (If you're Brit, don't smile.) The function that does the split on the string.

Description

This returns an anonymous splitter function.


Known Bugs

The regular expression parser does a very poor job with syntactically invalid regular expressions. Depending on the expression, the parser may signal an error, improperly parse it, or simply crash.

A regular expression that matches a large enough substring can produce a stack overflow. This can happen much more easily under d2c than under Mindy -- as few as two dozen lines of 80 column text under d2c for Windows.

Note: As the regular-expressions library is used to create d2c, it appears to be stable enough for most Dylan tasks -- even under Cygnus on Windows.


Chapter 12. The Transcendental Library

The Transcendental library contains functions on numbers. It includes commonly used numbers, such as pi and e, and the transcendental functions, including sine, cosine, and tangent, and their inverse (arc) and hyperbolic counterparts. Also included are the logarithmic family of functions (the various log functions and exp), and the square-root and power (^) functions.


Sine, Cosine, and Tangent

To understand the transcendental functions (particularly, sine, cosine, and tangent, and their friends), one must know about the relationships for a right triangle. The discussion will use the below reference figure:

Figure 12-1. A right triangle

Sine, cosine, and tangent are used when you know an angle and a length of one of the sides of a right triangle, and you want to know the length of another side. For these functions, the angle (theta) is in radians, not degrees. Using the reference diagram above, for sine, you work with the hypotenuse (AC) and the height (AB), for cosine, you work with the hypotenuse (AC) and the base length (BC), and for tangent, you work with the base and the height.


sin[Generic]

Returns the sine of a real number.

Synopsis

sin (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

Returns the sine of a real number. Using the above right triangle in Figure 12-1, the sine of theta is AB / AC. For example, say AC is 12 meters and theta is $double-pi / 6 (30 degrees). You solve for AB by multiplying AC and sine theta. AB = 12 * sin( $double-pi / 6.0) => 6 meters.


cos[Generic]

Returns the cosine of a real number.

Synopsis

cos (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

Returns the cosine of a real number. The cosine of theta is BC / AC. Problem: Given theta is $double-pi / 4 and BC is 7 meters, what length is AC? What is theta in degrees? (see the entry for $double-pi for help)


tan[Generic]

Returns the tangent of a real number.

Synopsis

tan (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

Returns the tangent of a real number. The tangent of theta is AB / BC. The canonical exercise for tangent is to compute the height of a building. Let's say you want to know how high your chimney is. You are standing 25 meters from the building, and the chimney is 4 hands above the ground (where a hand is equivalent to 12 degrees). How tall is your chimney?


The pi Constants

So, perhaps you are used to thinking in degrees, not radians. How do you convert between the two when you use the above functions? That's as easy as pi! If you have the angle in degrees and one of side lengths, first multiple that angle by pi / 180.0 (either $double-pi or $single-pi) to get radians, and then use that resulting theta in the appropriate function.

There are several engrossing exercises for computing pi, and several novel approaches. The most widely-known approach is to compute the value of the series 4 - 4/3 + 4/5 - 4/7 ... (which takes a very large number of terms to get close to Chuck Moore's find (see below)). Another is to use the Fibonacci numbers (see this article on computing pi using arc-tangents) which become usable in about ten terms.


$double-pi[Constant]

The approximation of pi for double-precision floating-point arithmetic.

Type

<double-float>

Description

The value here is 3.14159265358979323846. Chuck Moore, the inventor of the programming language Forth, chose instead to use 355 / 113 as pi (which is accurate to 3e-7), as computers at the time processed floating point operations too slowly for use in real-time applications.


$single-pi[Constant]

The approximation of pi for single-precision floating-point arithmetic.

Type

<single-float>

Description

This pi is a truncated value of $double-pi.


The Inverse (Arc) Functions

The next question that comes up is if you have two sides of the right triangle, and you need to know the angle. The arc functions of sine, cosine and tangent resolve this issue. Let's use the same reference diagram for the following discussion.

Figure 12-2. A right triangle

The arc sine function (asin, also known as the inverse sine) gives theta (the angle in radians) from the height (AB) over the hypotenuse (AC). The other arc functions, acos, and atan, behave as their more-familiar counterparts. So, the arc-cosine gives theta from the base (BC) and the hypotenuse (AC); the arc-tangent, from the height(AB) and the base (BC). Again, to convert from radians to degrees, multiple the result by 180 / pi.


asin[Generic]

Returns the arc-sine of a real number

Synopsis

asin (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

Given the hypotenuse (AC) and the height (AB), the arc-sine gives theta in the diagram: the angle in radians.


acos[Generic]

Returns the arc-cosine of a real number

Synopsis

acos (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

Given the hypotenuse (AC) and the base (BC), the arc-cosine gives theta in Figure 12-2: the angle in radians.


atan[Generic]

Returns the arc-tangent of a real number

Synopsis

atan (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

Given the height (AB) over the base (BC), the arc-tangent gives theta in the diagram: the angle in radians.


atan2[Generic]

Returns the arc-tangent of a pair of real numbers

Synopsis

atan2 (y, x) => (z)

Parameters

yAn instance of <real>.
xAn instance of <real>.

Return Values

zAn instance of <float>.

Description

Given the height (AB) as y and the base (BC) as x, the arc-tangent gives theta as z: the angle in radians.


The Hyperbolic Functions


sinh[Generic]

Returns the hyperbolic sine of a real number

Synopsis

sinh (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

Returns the hyperbolic sine of a real number.


cosh[Generic]

Returns the hyperbolic cosine of a real number

Synopsis

cosh (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

Returns the hyperbolic cosine of a real number.


tanh[Generic]

Returns the hyperbolic tangent of a real number

Synopsis

tanh (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

Returns the hyperbolic tangent of a real number.


asinh[Generic]

Returns the hyperbolic arc-sine of a real number

Synopsis

asinh (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

Returns the hyperbolic arc-sine of a real number.


acosh[Generic]

Returns the hyperbolic arc-cosine of a real number

Synopsis

acosh (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

Returns the hyperbolic arc-cosine of a real number.


atanh[Generic]

Returns the hyperbolic arc-tangent of a real number

Synopsis

atanh (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

Returns the hyperbolic arc-tangent of a real number.


The e Constants

I will leave aside the temptation to find mathematical similarities between pi and e, with the exception of stating that both can use the Fibonacci numbers to find close approximations of their values. e finds use for logarithmic and exponential calculations.


$double-e[Constant]

The approximation of e for double-precision arithmetic.

Type

<double-float>

Description

The value here is 2.7182818284590452354. To compute your own approximation, use the Fibonacci numbers (1, 1, 2, 3, 5, 8, 13, 21, ...). e = F(n) / F(n-1); where the larger n is, the more accurate e is.


$single-e[Constant]

The approximation of e for single-precision arithmetic.

Type

<single-float>

Description

This e is a truncated value of $double-e.


The Logarithmic Functions

The logarithmic family of functions (log in its various forms and exp) use e as their foundation.


log[Generic]

Returns the exponent of a number

Synopsis

log (x, #key base) => (y)

Parameters

xAn instance of <real>.
base:An instance of <real>. The number to which the exponent is applied to get x. The default is $double-e

Return Values

yAn instance of <float>.

Description

The log function scales large numbers, so that (e.g.) data points with a very large spread can be viewed together. log assumes $double-e as the base, but you may change that by supplying a different value. For example,

log(100000, base: 10) => 5.0
	  

exp[Generic]

Returns the e raised to a number

Synopsis

exp (x) => (y)

Parameters

xAn instance of <real>.

Return Values

yAn instance of <float>.

Description

exp returns e raised to the number supplied. You may be wondering what purpose this function serves, given $double-e and \^. Actually, exp is a favorite function of mine, because it is used in the compounding interest formula, which is: T = Pert (The resulting Total money is Principal multiplied by e to the rt power (rate times time)). So, 10000 USD will be over 33000 USD if held for twelve years in an account earning 10 percent, as shown by the result of:

10000 * exp(12 * 0.1)

How many years will it take to make 1000000 USD if you start investing 10000 USD at 21 percent and add 500 USD per month?


Chapter 13. The Time Library

Time is a library of routines for working with time and dates.


The Time Module

This module contains the basic time classes, encoding and decoding helper classes, functions to convert between times, and functions to get the current time.


<universal-time>[Constant]

A simple <general-integer> representation of the number of seconds since 00:00:00 1 January 1970, UTC.

Type

<integer> or <extended-integer>

Description

Using <extended-integer>s guarantees that you can represent any date after 1 Jan 1970. Using <integer>s will break for dates after a certain date (depending on $maximum-integer) and can sometimes cause unpredictable behavior.


<seconds>[Constant]

An <integer> between 0 and 59 inclusive.

Type

limited(<integer>, min: 0, max: 59)

Description

Ensures the seconds slot of <decoded-time> is valid.


<minutes>[Constant]

An <integer> between 0 and 59 inclusive.

Type

limited(<integer>, min: 0, max: 59)

Description

Ensures the minutes slot of <decoded-time> is valid.


<hours>[Constant]

An <integer> between 0 and 23 inclusive.

Type

limited(<integer>, min: 0, max: 23)

Description

Ensures the hours slot of <decoded-time> is valid.


<day-of-week>[Constant]

An <integer> between 0 and 6 inclusive.

Type

limited(<integer>, min: 0, max: 6)

Description

Ensures the day-of-week slot of <decoded-time> is valid. The first day of the week (or 0) is Monday.


<day-of-month>[Constant]

An <integer> between 1 and 31 inclusive.

Type

limited(<integer>, min: 1, max: 31)

Description

Ensures the day-of-month slot of <decoded-time> is valid.


<month>[Constant]

An <integer> between 1 and 12 inclusive.

Type

limited(<integer>, min: 1, max: 12)

Description

Ensures the month slot of <decoded-time> is valid.


<timezone>[Constant]

An <integer> between -86400 and 86400 inclusive.

Type

limited(<integer>, min: -86400, max: 86400)

Description

Ensures the timezone slot of <decoded-time> is valid. A <timezone> is the seconds west of UTC.


<year>[Constant]

A named <integer>

Type

<integer>

Description

Since every other slot in <decoded-time> has a named type, we didn't want the year slot to be lonely.


<decoded-time>[sealed Class]

Decoded time is for representing absolute times in a nice human readable way.

Superclasses

<object>

Initialization Keywords

seconds:An instance of <seconds>. 0 to 59 Defaults to #f.
minutes:An instance of <minutes>. 0 to 59 Defaults to #f.
hours:An instance of <hours>. 0 to 23 Defaults to #f.
day-of-week:An instance of <day-of-week>. 0 to 6 Defaults to #f.
day-of-month:An instance of <day-of-month>. 1 to 31 Defaults to #f.
month:An instance of <month>. 1 to 12 Defaults to #f.
year:An instance of <year>. Year can be any integer (even negative ones); however, <decoded-time> starts from 1970. Defaults to #f.
daylight-savings-time?:An instance of <boolean>. Is this decoded time adjusted for daylight savings time Defaults to (uninitialized).
timezone:An instance of <timezone>. -86400 to 86400. If this keyword specified, the functions in the time library assume that it is the correct timezone and ignore the daylight-savings-time? flag. Therefore if you encode a <decoded-time> with the timezone representing EST and the daylight-savings-time? flag set to #t, it will convert the time assuming the local timezone is EST, not EDT. Defaults to #f.
default-from:An instance of <decoded-time>. Allows initialization from another <decoded-time> instance. If default-from: is specified, any slot that isn't specified via an init-keyword will take its value of the this slot's object. If this keyword is not specified, any slot not specified via an init-keyword will have a value of #f. Defaults to $null-decoded-time.

Description

Note that there's no point in not defining a print-object method, since the parse-time stuff already uses streams. Might as well use print and format, too.

We don't write "hh:mm:ss mm/dd/yy" or anything clever like that because it might not look so hot with undefined slots. (Besides, mm/dd/yy is rather ambiguous)


$null-decoded-time[Constant]

A <decoded-time> where all the slots are initialized to #f

Type

<decoded-time>

Description

This is an internal constant used to default the <decoded-time> when the default-from: keyword is used.


$default-time[Constant]

A <decoded-time> where all the slots are initialized to 0 or 1 (or, in the case of daylight-savings-time?, #f)

Type

<decoded-time>

Description

This constant gives a "0" <decoded-time>. Of note here is that the year slot is initialized to 0, not 1970. Is this an error?


get-universal-time[Method]

Return the current time as a <universal-time>.

Synopsis

get-universal-time () => (current-time)

Parameters

None.

Return Values

current-timeAn instance of <universal-time>.

Description

Recall that <universal-time> is an <integer> (seconds) from 01 Jan 00:00:00Z 1970. Use other functions to decode this value.


get-decoded-time[Method]

Return the current time as a <decoded-time>.

Synopsis

get-decoded-time (#key timezone) => (current-time)

Parameters

timezone:An instance of <timezone>. If supplied, uses the timezone to convert the current universal time.

Return Values

current-timeAn instance of <decoded-time>.

Description

This gives the current time, this time decoded into the appropriate slots. If timezone is supplied, then that time is converted to the time in that timezone.


decode-time[Method]

Decode a <universal-time>

Synopsis

decode-time (universal-time, #key timezone) => (decoded-time)

Parameters

universal-timeAn instance of <universal-time>. The time to be decoded
timezone:An instance of <timezone>. If supplied, uses the timezone to convert the current universal time.

Return Values

decoded-timeAn instance of <decoded-time>.

Description

Decode a <universal-time> into a <decoded-time> using the supplied timezone.


encode-time[Method]

Encode a <decoded-time>

Synopsis

encode-time (decoded-time) => (universal-time)

Parameters

decoded-timeAn instance of <decoded-time>. The time to be encoded

Return Values

universal-timeAn instance of <universal-time>.

Description

Encode a <decoded-time> into the universal time format.


encodable-time?[Method]

Sees if time can be encoded.

Synopsis

encodable-time? (time) => (result)

Parameters

timeAn instance of <decoded-time>. The time to be tested

Return Values

resultAn instance of <boolean>.

Description

Returns #t if time may be encoded. A <decoded-time> is encodable if all of its slots are specified, except possibly day-of-week.


as[Method]

Provides the as interface to get a <decoded-time>.

Synopsis

as (cls, universal-time) => (decoded-time)

Parameters

clsAn instance of singleton(<decoded-time>). The type of the instance returned
universal-timeAn instance of <universal-time>. the instance to decode

Return Values

decoded-timeAn instance of <decoded-time>.

Description

Decode a <universal-time> into a <decoded-time> the timezone is 0 for this method.


The Time-IO Module

This module contains functions for basic time input and output.


format-time[Method]

Writes a <decoded-time> to a <stream> according to a format-string directive.

Synopsis

format-time (stream, format, time) => ()

Parameters

streamAn instance of <stream>. Where the formatted time is going
formatAn instance of <string>. The instructions for formatting the time
timeAn instance of <decoded-time>. The time instance to format

Return Values

None.

Description

Format a <decoded-time> for output on a <stream>. The format arguments are described in the next section.


parse-time[Function]

Takes data on a stream and applies format arguments to return a <decoded-time>.

Synopsis

parse-time (input, format-string) => (res)

Parameters

inputAn instance of <stream>. Contains input data to be converted
format-stringAn instance of <string>. Contains formatting directives (described in Time-IO) to parse the data on the stream into a <decoded-time> instance.

Return Values

resAn instance of <decoded-time>.

Description

Very useful function for when (e.g.) a user is asked to enter time information, or when (e.g.) reading in a text file of records which include dates or times. Parse-time allows the program to convert the input into a <decoded-time> instance.

This module contains two internal classes that provide information on the parse process


<parse-time-error>[sealed Class]

Contains the error in parsing time format directives.

Superclasses

<error>

Initialization Keywords

parse-state:An instance of <parse-state>. The <parse-state> class is described below
error-format-string:An instance of <string>. The control string for textual error representation
error-format-args:An instance of <sequence>. The arguments to the format-string

Description

The error we signal when we have trouble parsing something. Note that an unknown format directive is *not* considered a <time-parsing-error>, but a normal, unnamed (and close to uncatchable) error.


<parse-state>[sealed Class]

A parser containing the input stream, the formatting directives, and information about the status on the parse process.

Superclasses

<object>

Initialization Keywords

format-string:An instance of <string>. The format-string we are trying to parse the time with
format-stream:An instance of <stream>. format-string, as a stream
input-stream:An instance of <stream>. The stream we're trying to parse

Description

This class contains several other slots containing information about the parse state:

  • current-directive: The directive we're currently trying to process, or #f if we're not trying to process one. Used by the error handling stuff to give informative messages.

  • parsed-hour: slot used when parsing 12-hour hours. Untouched when parsing 24-hour hours.

  • pm?: (defaults to #f), a parsed-hour helper.

  • parsed-day-of-year: We change this if we're asked to read in a day-of-year. Since we can't make sense of a day-of-year without knowning if it's a leap-year (and thus, knowing the year), we delay processing of this information

  • parsed-year: Used for processing day-of-year. The <decoded-time> doesn't actually get it's year from this slot, it gets that from the init-args.


Parse-Time Directives

The following directives tell how to print or to parse times.

  • %a -- abbreviated weekday name

  • %A -- full weekday name

  • %b -- abbreviated month name

  • %B -- full month name

  • %c -- local date and time representation

  • %d -- day of the month (01-31)

  • %H -- hour (24-hour clock) (00-23)

  • %I -- hour (12-hour clock) (01-12)

  • %j -- day of the year (001-366)

  • %m -- month (01-12)

  • %M -- minute (00-59)

  • %p -- local equivalent of AM or PM

  • %S -- second (00-59)

  • %U -- week number of the year (Sunday as 1st day of the week) (00-53)

  • %w -- weekday (0-6, Sunday is 0)

  • %W -- week number of the year (Monday as 1st day of the week) (00-53)

  • %x -- local date representation

  • %X -- local time representation

  • %y -- year without century (00-99)

  • %Y -- year with century

  • %Z -- time zone name, if any

  • %% -- the % character

See the Section called Complex Example Using the %m Directive in Chapter 5, which demonstrates using these time-formatting commands to display time in a human-readable format.


Chapter 14. The Random Library

The Random library provides random number support in several random number distributions. This is a replacement for David Pierce's Random library. This one is strongly based on Common Lisp. Much of the implementation has been translated from CMUCL's rand.lisp, which was written by David Adam. Code that turns a uniform random distribution into Gaussian and exponential distributions has been adapted from David Pierce's library.


The Random Module


random[Method]

Generates a random integer

Synopsis

random (arg, #key state) => (random-number)

Parameters

argAn instance of <integer>. Maximum number generated
state:An instance of <random-state>. The state used to generate the random number Defaults to *random-state*.

Return Values

random-numberAn instance of <integer>.

Description

Return a random integer between 0 (inclusive) and arg (exclusive). We return the same kind of integer that arg is.


random-bits[Method]

Generates a random series of bits

Synopsis

random-bits (#key state) => (bits)

Parameters

state:An instance of <random-state>. The state used to generate the random bit series. Defaults to *random-state*.

Return Values

bitsAn instance of <integer>.

Description

Returns a fixed integer that has $random-bits-count random bits. This function is the fastest way to get a random series of bits.


$random-bits-count[Constant]

Number of bits returned by random-bits.

Type

<integer>

Description

The computation of this constant takes the upper bound integer (a number larger than 1e+9) bit size and adjusts to avoid loss of randomness near the limit.


<random-state>[ sealed instantiable Class]

Used to compute a random number

Superclasses

<object>

Initialization Keywords

None.

Description

The <random-state> has slots that maintain a seed state so that a new random number can be generated.


*random-state*[Variable]

An instance that maintains the random state

Type

<random-state>

Description

Used, by default, to compute random integers and series of bits


Chapter 15. The Matrix Library

This library implements some basic matrix operations. These functions are not guarenteed to be stable or numerically sound, nor are they very optimized, but for smaller applications they should be suitable.

The <matrix> class is a subclass of <array>, so all operations on <array>s and collections in general should work as expected. One important limitation of matrices is that they are limited to two dimensions, and trying to use any other size results in an error. The <matrix> class has two ways to get instances and several operations for those instances.


Initialization


<matrix>[sealed Class]

Meta-information container

Superclasses

<array>

Initialization Keywords

None.

Description

This class contains two slots: dimensions, a <sequence>, which contains the two values of the size of the matrix, and components, a <simple-object-vector>, that contain the matrix elements.


initialize[Method]

Used by make to create instances of a <matrix>

Synopsis

initialize (#key dimensions, fill) => (mat)

Parameters

dimensions:An instance of <object>. A sequence of two elements which represent the rows and column of the matrix respectively Defaults to #[1, 1].
fill:An instance of <object>. The objects that each element of matrix should be initialized to Defaults to 0.

Return Values

matAn instance of <matrix>.

Description

Use make with the above keywords to obtain a <matrix> instance


matrix[Method]

Create instances of a <matrix> from a list of <vector>s

Synopsis

matrix (#rest row-vectors) => (mat)

Parameters

row-vectorsInstances of <object>.

Return Values

matAn instance of <matrix>.

Description

This method takes a list of <vectors> and creates a <matrix> instance from them, for example:

let mat = matrix(#[1, 1, 2], #[3, 5, 8], #[13, 21, 34]);
	  

creates a 3x3 matrix.

Note: The row-vectors must all be of the same size.


identity-matrix[Method]

Creates the identity matrix

Synopsis

identity-matrix (#key dimensions) => (mat)

Parameters

dimensions:An instance of <object>. Note: enter 2 dimensions for the matrix, an error may occur if both dimensions are not equal. Defaults to #[1, 1].

Return Values

matAn instance of <matrix>. The identity matrix, sized to dimensions

Description

This function simply returns the identity matrix of the specified dimension. It is a very simple algorithm, it merely fills a matrix with zeros, and then puts ones down the diagonal.


Matrix Operations

These are operations on matrices. The include the "simple" arithmetic operations (\+, \-, \*), as well as other standard matrix operations, such as inverse, transpose, augment, and gauss-jordan elimations.


\+[Method]

Adds two matrices.

Synopsis

\+ (matrix1, matrix2) => (summation-matrix)

Parameters

matrix1An instance of <matrix>.
matrix2An instance of <matrix>.

Return Values

summation-matrixAn instance of <matrix>.

Description

Adds two matrices. This is a binary operator that performs matrix addition on the matrices "matrix1" and "matrix2", storing the result in a new matrix "temp-mat", "temp-mat" is then returned on exit. Matrix addition is very simple, all it is is adding terms in corresponding positions


\-[Method]

Subtracts two matrices.

Synopsis

\- (matrix1, matrix2) => (difference-matrix)

Parameters

matrix1An instance of <matrix>.
matrix2An instance of <matrix>.

Return Values

difference-matrixAn instance of <matrix>.

Description

Matrix subtraction is (surprise) just like matrix addition, where the element i,j in (A - B) is (A[i,j] - B[i,j])


\*[Method]

Multiplies a matrix by a scalar.

Synopsis

\* (a, matrix1) => (product-matrix)

Parameters

aAn instance of <number>.
matrix1An instance of <matrix>.

Return Values

product-matrixAn instance of <matrix>.

Description

Multiplication of a matrix and a scalar quantity. This simply multiplies each element of the matrix by the scalar quantity.


\*[Method]

Multiplies a matrix by a scalar.

Synopsis

\* (a, matrix1) => (product-matrix)

Parameters

aAn instance of <number>.
matrix1An instance of <matrix>.

Return Values

product-matrixAn instance of <matrix>.

Description

Same as the above \*, with the opposite order of the parameters.


\*[Method]

Multiplies two matrices.

Synopsis

\* (matrix1, matrix2) => (mult-matrix)

Parameters

matrix1An instance of <number>.
matrix2An instance of <matrix>.

Return Values

mult-matrixAn instance of <matrix>.

Description

Multiplies two matrices. There are certain restrictions on what matrices can be multiplied. To multiply two matrices, the dimensions must be MxN for the first matrix, and NxP for the second. The result of the multiplication will be an MxP matrix. (Note, this implies A * B is not necessarily equal to B * A) The element i,j in A * B is the dot (inner) product of the ith row of A with the jth column of B. The dot product of a vector is the sum of the products of corresponding elements. That is, if vector V=[a,b,c,d] and vector W=[w,x,y,z] then V*W= aw + bx + cy + dz (Note that this is a scalar quantity).

The actual algorithm used was reproduced from Sedgewick's Algorithms, Ch. 36. Basically, the algorithm goes through the temporary matrix, filling out each element in the following way: For the i,jth element of the matrix, calculate the dot product an element at a time, by having a number k range from 0 to the dimension N of the matrix. Take A[i,k] and multiply it by B[k,j] to get one of the terms in the dot product. Continue this for each element in the MxP matrix to get the result.


augment-matrix[Method]

A special way to concatenate two matrices.

Synopsis

augment-matrix (matrix1, matrix2) => (augmented-matrix)

Parameters

matrix1An instance of <number>.
matrix2An instance of <matrix>.

Return Values

augmented-matrixAn instance of <matrix>.

Description

The augment-matrix procedure will take matrices A and B and return a matrix | A B |.


gauss-jordan[Method]

Does a Gauss-Jordan elimination on a matrix.

Synopsis

gauss-jordan (matrix1) => (solution-matrix)

Parameters

matrix1An instance of <number>.

Return Values

solution-matrixAn instance of <matrix>.

Description

This procedure does gauss-jordan elimation on a matrix of dimension N by N + 1. The first N columns are the coefficents in a set of simultaneous equations, and the last column is a solution vector. The matrix that is returned is an N by 1 matrix contaning the solution for each variable. For example, if you have a system of equations like this:

 2x + 4y - 2z = 2
 4x + 9y - 3z = 8
-2x - 3y + 7z = 10 
	  

The matrix representing this would be

|  2  4 -2  2 |
|  4  9 -3  8 |
| -2 -3  7 10 |
	  

The solution matrix returned would be:

| -1 |
|  2 |
|  2 |
	  

where x is -1, y is 2, and z is 2


inverse[Method]

Finds the inverse of a matrix.

Synopsis

inverse (matrix1) => (inverted-matrix)

Parameters

matrix1An instance of <number>.

Return Values

inverted-matrixAn instance of <matrix>.

Description

Finds the inverse of a matrix, by using a modified gauss-jordan elimination. Given any matrix, if there is an inverse, the inverse will be returned, otherwise, an error will be signalled. To determine the existance of an inverse, the algorithm finds the upper triangular matrix, and then multiplies all of the elements along the main diagonal. If the result of this multiplication is zero, there is no inverse, otherwise, there is gaurenteed to be an inverse.


det[Method]

Returns the determinant of a matrix.

Synopsis

det (matrix1) => (determinant)

Parameters

matrix1An instance of <number>.

Return Values

determinantAn instance of <number>.

Description

This just does what the first half of inverse does. It reduces the matrix to the upper triangular form, and then returns the product of all of the elements along the diagonal. This is the determinant of the matrix.


inverse[Method]

Returns the matrix transposed.

Synopsis

inverse (matrix1) => (transposed-matrix)

Parameters

matrix1An instance of <number>.

Return Values

transposed-matrixAn instance of <matrix>.

Description

This function transposes a matrix. It takes a M by N matrix and turns it into an N by M matrix. All it does is take the i,jth element in the M by N matrix, and turns it into the j,ith element in the N by M matrix.


Chapter 16. The Parse-Arguments Library

The Parse-Arguments library provides a simple and flexible way to parse the command-line arguments of a Dylan program. It provides support for the most common types of command-line options, and can be extended to suit the needs of a particular application.


Terminology

The Parse-Arguments library uses a standard set of terminology for representing the tokens which might appear on a command line.

Figure 16-1. Sample command line.

$ sample-app -v --repeat -n=10 foo.txt -- bar.txt
application name

The application name appears first on the command line. Under Unix-like systems, the application name is passed to the program exactly as typed. In particular, it may be the name of a symlink or include one or more directory components.

command-line arguments

Everything appearing after the application name is a command-line argument.

regular argument

In Figure 16-1, foo.txt and bar.txt are regular arguments.

option

Options are also known as flags and switches. They control the behavior of the application, and may appear in one of two forms. Short options always appear after a single dash, but several of them may be grouped together (e.g. -tzvf in GNU tar). In Figure 16-1, -v and -n are both short options. Long options such as --repeat consist of entire words and are always preceded by two dashes.

parameter

Parameters modify the behavior of an option. In Figure 16-1, the 10 following -n is a parameter. Note that the equals sign may be surrounded by white space or omitted entirely where unambiguous.

option terminator

The double dash without an option name is called an option terminator. Any arguments appearing after the terminator are automatically regular arguments, even if they begin with a dash.


A Simple Example

Figure 16-2 and Figure 16-3 demonstrate how to use the parse-arguments library in a simple application.

Figure 16-2. Library declaration for a sample application using parse-arguments.

Module: dylan-user

define library sample-application
  use dylan;
  use format-out;
  use parse-arguments;
end library;

define module sample-application
  use dylan;
  use extensions;
  use format-out;
  use parse-arguments;
end module;

Figure 16-3. Source code for a sample application using parse-arguments, making use of the define argument-parser macro.

Module: sample-application

define argument-parser <sample-parser> ()
  option verbose?, long: "verbose", short: "v";
  option logfile, kind: <parameter-option-parser>, long: "logfile", short: "L";
  regular-arguments file-names;
end;

define method main(program-name :: <string>, #rest arguments)
  let parser = make(<sample-parser>);

  unless (parse-arguments(parser, arguments))
    format-out("Usage: %s [-v] [-Llogfile] files...\n", program-name);
    exit(exit-code: 1);
  end;

  // Body of program.
end;

In Figure 16-3, the variable parser.verbose? will be set to #t if either --verbose or -v appears on the command line. Otherwise, it will be set to #f. Similarly, if -Lfilename or --logfile=filename appears on the command line, the variable parser.logfile will be set the string "filename". Otherwise, it too will be set to #f.

Any other arguments will be collected and placed in the variable parser.file-names.

Figure 16-4 shows how to use the Parse-Arguments library without using the define argument-parser macro. Here the various arguments are added manually, and accessed using the option-value-by-long-name method.

Figure 16-4. Source code for a sample application using parse-arguments.

Module: sample-application

define method main(program-name :: <string>, #rest arguments)
  let parser = make(<argument-list-parser>);
  add-option-parser-by-type(parser,
                            <simple-option-parser>,
                            long-options: #("verbose"),
                            short-options: #("v"));
  add-option-parser-by-type(parser,
                            <parameter-option-parser>,
                            long-options: #("logfile"),
                            short-options: #("L"));

  unless (parse-arguments(parser, arguments))
    format-out("Usage: sample-application [-v] [-Llogfile] files...\n");
    exit(exit-code: 1);
  end;

  let verbose? = option-value-by-long-name(parser, "verbose");
  let logfile = option-value-by-long-name(parser, "logfile");
  let file-names = parser.regular-arguments;

  // Body of program.
end;

Using the define argument-parser is the preferred way of using the Parse-Arguments library. It is both more convenient and better readable. The manual way is documented both for users of Mindy, which doesn't have macro capabilities, and for advanced users who wish to extend the functionality of the option parsers.


Parsing Arguments

To parse a command-line, you create a new <argument-list-parser>, connect a number of individual <option-parser>s, call parse-arguments, and use the resulting information.


Argument List Parsers


<argument-list-parser>[Sealed Class]

Describes how to parse an argument list, and contains the data found when parsing one.

Superclasses

<object>

Initialization Keywords

None.

Description

An <argument-list-parser> represents both a description of the data to be found in an argument list, and the results of parsing a particular argument list for that data.

Prior to calling parse-arguments for the first time, no useful information can be extracted from an argument list parser. Subsequent calls to parse-arguments will update the data contained within the parser.


regular-arguments[Function]

Returns the regular arguments found by parsing an argument list.

Synopsis

regular-arguments (parser) => (arguments)

Parameters

parserAn instance of <argument-list-parser>.

Return Values

argumentsAn instance of <sequence>.

Description

After calling parse-arguments, this function can be used to find all of the regular arguments that weren't consumed by any option parser.


Option Parsers


<option-parser>[Abstract Open Primary Class]

Parses a single command-line option and any parameters.

Superclasses

<object>

Initialization Keywords

long-options:An instance of <list>. Specifies the long options handled by this parser, represented as strings. Defaults to #().
short-options:An instance of <list>. Specifies the short options handled by this parser, represented as strings. Defaults to #().

Description

Different types of command-line options are parsed according to different rules. An <option-parser> knows how to handle one type of option. The long-options: and short-options: keywords are used to specify which option names should be handled by a given parser.

An option parser can be connected to an <argument-list-parser> for and the values to be found.


option-present?[Function]

Tests whether an option was present on the command-line.

Synopsis

option-present? (parser) => (present?)

Parameters

parserAn instance of <option-parser>.

Return Values

present?An instance of <boolean>.

Description

Returns #t if and only if parse-arguments found at least one corresponding option on the command line. Returns #f if parse-arguments has not been called.


option-value[Function]

Returns the value found by an option parser after processing the command line.

Synopsis

option-value (parser) => (value)

Parameters

parserAn instance of <option-parser>.

Return Values

valueAn instance of <object>.

Description

Returns the value calculated by parser after running parse-arguments. Returns #f if parse-arguments has not been called.

The exact type of value will vary depending on the class of the option parser.


Parsing an Argument List


add-option-parser[Function]

Attaches an <option-parser> to an <argument-list-parser>.

Synopsis

add-option-parser (args-parser, option-parser) => ()

Parameters

args-parserAn instance of <argument-list-parser>.
option-parserAn instance of <option-parser>.

Return Values

None.

Description

Attaches an <option-parser> to an <argument-list-parser>. It is an error to attach an <option-parser> more than once, and no mechanism is provided to detach one.


add-option-parser-by-type[Function]

Create an <option-parser> and add it to an <argument-list-parser>.

Synopsis

add-option-parser-by-type (args-parser, option-parser-type, #rest init-keys) => ()

Parameters

args-parserAn instance of <argument-list-parser>.
option-parser-typeAn instance of subclass(<option-parser>). The class for the new option parser.
init-keysInstances of <object>. Inititialization keywords for for the new option parser.

Return Values

None.

Description

This function is equivalent to calling:

let opt-parser =
  apply(make, option-parser-type, init-keys);
add-option-parser(args-parser, opt-parser);

Most programs will use this function instead of add-option-parser.


parse-arguments[Function]

Parses a list of command-line arguments.

Synopsis

parse-arguments (parser, argument-list) => (success?)

Parameters

parserAn instance of <argument-list-parser>.
argument-listAn instance of <sequence>. The strings to be parsed.

Return Values

success?An instance of <boolean>.

Description

This routine does most of the work in the Parse-Arguments library. It performs a number of different steps:

  1. Split the argument list. If the string "--" appears in the argument list, discard it, and set aside everything to right for later processing.

  2. Chop individual arguments around any equals sign. If any argument contains the character '=', break the argument into three strings: everything before the first occurance of the equals sign, the sign itself, and the remainder of the original string.

  3. Tokenize the argument list. Convert the argument list into a series of tokens. For more details on this process, see the Section called Writing New Option Parser Classes.

  4. Process the argument list from left to right. For each option token, invoke the appropriate option parser (which may consume additional tokens). Record all regular argument tokens for later use. If any other kinds of tokens appear in the argument list, they must be consumed by an option parser or the entire process will fail.

  5. Collect the regular arguments. Take the regular arguments found while parsing, and append any arguments set aside in the first step.

If an error occurs during this process, parsing will stop immediately and parse-arguments will return #f. Otherwise, it will return #t.


option-parser-by-long-name[Function]

Find an option parser, given a corresponding option name.

Synopsis

option-parser-by-long-name (parser, long-name) => (option-parser)

Parameters

parserAn instance of <argument-list-parser>.
long-nameAn instance of <string>.

Return Values

option-parserAn instance of <option-parser>.

Description

This function can be used to recover an option parser previously attached to an <argument-list-parser>.


option-present?-by-long-name[Function]

Determine whether an option was present, given a corresponding option name.

Synopsis

option-present?-by-long-name (parser, long-name) => (present?)

Parameters

parserAn instance of <argument-list-parser>.
long-nameAn instance of <string>.

Return Values

present?An instance of <boolean>.

Description

This function provides an easy way to determine whether a given option parser found anything in an argument list.

Note: If an option has multiple names, any one of them can be used as the argument to this function without changing the result.


option-value-by-long-name[Function]

Find the value of an option, given a corresponding option name.

Synopsis

option-value-by-long-name (parser, long-name) => (value)

Parameters

parserAn instance of <argument-list-parser>.
long-nameAn instance of <string>.

Return Values

valueAn instance of <object>.

Description

This function provides an easy way to find the value of a particular option parser.

Note: If an option has multiple names, any one of them can be used as the argument to this function without changing the result.


Standard Option Parser Classes

Parse-Arguments supports the most popular types of POSIX and GNU command-line options.


<negative-option-parser>[Abstract Open Class]

Parses command-line options which may appear in positive and negative forms.

Superclasses

<option-parser>

Initialization Keywords

negative-long-options:An instance of <list>. Specifies the negative long options handled by this parser, represented as strings. Defaults to #().
negative-short-options:An instance of <list>. Specifies the negative short options handled by this parser, represented as strings. Defaults to #().

Description

This class is exported from the module option-parser-protocol. We document it here because it is the superclass of <simple-option-parser>.

Certain command-line options appear in a positive and negative form. For example, many programs accept --verbose and --quiet options.

This class provides internal support for creating parsers to handle such options. It cannot be instantiated.


<simple-option-parser>[Sealed Class]

Parses options without any parameters.

Superclasses

<negative-option-parser>

Initialization Keywords

default:An instance of <boolean>. Specifies the value returned by this option parser if no applicable options appear on the command line. Defaults to #f.

Description

Simple options have no parameters, and may appear in both positive and negative forms. When parsing a list of arguments, option-value is first set to the default. As the command line is then scanned from left to right, each positive option sets the value to #t and each negative option sets it to #f.

This behavior is consistent with that of the utility rm, which allows the user to set default options with a shell alias of the form alias rm="rm -i". Such defaults can be overriden by explicity passing a flag when calling rm because the rightmost value takes precedence.

Option Forms

-q, --quiet, -v, --verbose


<parameter-option-parser>[Sealed Class]

Parses options which have a parameter and which may appear only once.

Superclasses

<option-parser>

Initialization Keywords

None.

Description

A <parameter-option-parser> sets option-value to either #f or a <string>. If the option appears more than once on the command line, the rightmost value is used.

Option Forms

-fname, -f name, -f=name, -f = name, --file name, --file=name, --file = name


<repeated-parameter-option-parser>[Sealed Class]

Parses options which have a parameter and which may appear more than once.

Superclasses

<option-parser>

Initialization Keywords

None.

Description

A <repeated-parameter-option-parser> sets option-value to a <sequence> of strings.

Option Forms

-fname, -f name, -f=name, -f = name, --file name, --file=name, --file = name


Writing New Option Parser Classes

This section is empty.