git @ Cat's Eye Technologies define-opaque / 0.3
0.3

Tree @0.3 (Download .tar.gz)

define-opaque

This library contains some macros in R5RS Scheme that define opaque data structures. They are based on the examples given in the article Information Hiding in Scheme.

The macros allow the creation of data structures whose details are properly hidden, observable and manipulable only by the code internal to the defined operations of the data structure; direct access to it by other means is prevented.

The macros are defined in the Scheme file src/define-opaque-0.3.scm. The idea is that you'd just copy it into your project and (load "define-opaque-0.3.scm") where you need it.

The macros are not intended for production use, but since they are very simple, I would encourage you to read them (each definition easily "fits on a page") and decide that for yourself.

Basic Usage

There are two macros, define-opaque-adt and define-opaque-object.

The difference between the two relates closely to the comparison of abstract data types and objects in William Cook's 2009 essay On Understanding Data Abstraction, Revisited.

The arguments to the define-opaque-adt macro are

  • the name of the opaque data structure that will result (visible globally)
  • the name of a function which creates a new instance of the data structure (visible only to the operations)
  • the name of a function which opens an instance, returning its internal value; can be called on operation parameters to verify their type (visible only to the operations)
  • the name of the private variable used internally (visible only to the operations)
  • the default value for that variable
  • a list of operations. Each operation is a 2-element list, consisting of its name, and a lambda expression giving its implementation.

The arguments to the define-opaque-object macro are

  • the name of the opaque data structure that will result (visible globally)
  • the name of a function which creates a new instance of the data structure (visible only to the operations)
  • a list of names for the private data items used internally (visible only to the operations)
  • a list of the values to be taken on by default by the internal names (must match length of previous list)
  • a list of operations, in the same form as for define-opaque-adt

In both cases, the opaque data structure that results is a Scheme function. When it is called, the first argument must be the name of an operation; the remainder of the arguments are passed to the internal implementation of the operation.

For define-opaque-object, the data structure that is created by the macro is typically treated as a "prototype", and conventionally defines an operation called new that provides a way to initialize a new instance of the data structure itself, possibly based on some given initialization parameters.

If the opaque data structure does not support an operation with the given name, a procedure called error will be called. Some Schemes, such as Chicken, provide this as a built-in procedure; if your Scheme does not, you might want to provide an implementation before loading define-opaque-0.3.scm. (But if you don't, your Scheme should error out anyway when it tries to call error, which is exactly the intent, so it shouldn't be a big deal.)

If the above description is unclear, the example programs in the eg directory may help illuminate the usage patterns:

stack.scm

First-in, first-out stack, with operations push, top, and pop.

stack-expanded.scm

Contains a manually expanded version of the stack data structure for illustration purposes.

proper-list.scm

Proper cons lists, where the tail of a list must be another list (cons cell or nil) and not value of some other type, like number.

Note that define-opaque-object can't actually enforce this property in the way define-opaque-adt can.

a-small-logic.scm

An LCF-style adaptation of the tiny proof system given in section 4 ("A Small Logic") in Logic as Algebra (1998) by Paul Halmos and Steven Givant. It preserves the additive properties of parity.

Note that define-opaque-object can't actually enforce the needed properties of the LCF architecture in the way define-opaque-adt can.

hilbert-system.scm

An LCF-style implementation of a Hilbert-style proof system for propositional logic, with two axioms. This is defined as an ADT so that it can enforce the restrictions of the LCF architecture.