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.
Commit History
@master
git clone https://git.catseye.tc/define-opaque/
- Stylistic (mostly) updates to README in prep for release of 0.3. Chris Pressey 9 days ago
- Enrich the proper list example. Chris Pressey 10 days ago
- Add comment to a-small-logic.scm noting the limitations. Chris Pressey 10 days ago
- Demonstrate integrity of define-opaque-adt more thoroughly. Chris Pressey 10 days ago
- Updates to README to cover both macros now in this library. Chris Pressey 10 days ago
- Implement define-opaque-adt, and add example for it. Chris Pressey 11 days ago
- The macro is called `define-opaque-object` now. Add test script. Chris Pressey 11 days ago
- Move licensing info from .reuse/dep5 file into individual files. Chris Pressey 1 year, 10 months ago
- Adjust SPDX fields to better conform to the REUSE 3.0 spec. Chris Pressey 2 years ago
- Aesthetics. Chris Pressey 2 years ago