On this page:
3.1 String Representations
zo->string
zo->spec
3.2 Traversing zo Structs
zo-transition
3.3 Search
find
result
6.1.1.7

3 API

These functions support the REPL, but may be useful in more general settings.

3.1 String Representations

The file zo-string.rkt exports two functions and a contract. Broadly, these functions work to convert a zo struct to a human-readable string. But zo->spec returns a structured list, just before the full-on string representation, for programming convenience.

procedure

(zo->string z #:deep? deep)  string?

  z : zo?
  deep : boolean?
Convert a zo struct into a string. When the optional argument #:deep? is set, include the struct’s fields in the string representation. Otherwise, only print the name.

procedure

(zo->spec z)  spec/c

  z : zo?
Convert a zo struct into a spec/c representation. This is a structured list of strings—not quite as pretty, but easier to program with.

Specs are a list containing:
  • A string, representing its name.

  • Pairs, representing the struct’s fields. The first element of each pair should be a string representing the field name. The second element should be a thunk that, when forced, yields either a string or another spec.

The thunks prevent an entire struct from being converted at once.

3.2 Traversing zo Structs

The file zo-transition.rkt accomplishes a very simple task. Given a zo struct z and a string str, it attempts to look up the field named str within z. That’s it, and it takes about 500 lines of code to do so.

The sole exported function is:

procedure

(zo-transition z str)

  
(values (or/c zo? (listof zo?)) boolean?)
  z : zo?
  str : string?
Identify what specific zo struct z is, then access its field named str, if any. The multiple return values deal with the following cases:
  • If the field str does not exist, or does not denote a zo struct, return the argument z and the boolean value #f.

  • If the field str denotes a list and we can parse zo structs from the list, return a list of zo structs and the boolean #t.

  • (Expected case) If the field points to a zo struct, return the new zo struct and the boolean #t.

3.3 Search

If you know the name of the zo struct you hope to find by exploring a subtree, you can automate the exploring. Literally, find is repeated application of zo->string and zo-transition.

procedure

(find z str)  (listof result?)

  z : zo?
  str : string?
Starting with the children of the struct z, search recursively for struct instances matching the string str. For example, if str is "application" then find will return all application structs nested below z.

The return value is a list of result structs rather than plain zo structs because we record the path from the argument z down to each match.

struct

(struct result (z path)
    #:transparent)
  z : zo?
  path : (listof zo?)
A result is really just a pair: a zo struct and a path leading to it. In the context of find, the path is always from the struct find was called with.