Appendix A. Programming Walkthrough of the Hermes Language
Two programming walkthroughs (Bell, et al., 1991) were conducted of the Hermes language after an initial version of the language had been implemented and its functionality tested. The purpose of the programming walkthrough method is to evaluate the "writability" of a programming language during its design phase by carefully considering the steps that a programmer must go through in order to complete a programming task in the language. In particular, note is made of the "doctrines" (or pieces of knowledge) that one must have mastered in order to use the language. The method pinpoints factors in the design of the language that require large amounts of background knowledge.
In a series of sessions during April, 1992, the programming walkthrough methodology was carefully followed for a sample task in the Hermes language. The language designer defined the task, briefly described the language with several simple examples and a copy of the BNF syntax, served as a resource about the language, and indicated whether or not progress was being made with the task. A professor of computer science who is particularly interested in end-user programming languages worked through the task. A Ph.D. student in computer science who had investigated the programming walkthrough methodology and had conducted many sessions with it, assisted in carrying through the programming walkthrough methodology.
In August, 1992, the walkthrough was repeated with a similar set of participants. This second walkthrough substantially confirmed the findings of the first one. For the sake of logical presentation, results of the two sessions will be merged together in the discussion here. First, the various steps in solving the task will be laid out and the potential problem areas that were uncovered will be described. Then a list of redesign decisions will be presented, describing the rationale of the version of the language that emerged in response to these evaluations.
The task. The task for the programming walkthrough was to write a query statement in the language to accomplish the following: list people with four or more grandchildren. The participants in the first walkthrough were given a copy of the BNF syntax of a simplified form of the language. Those in the second walkthrough were given a screen image of the interface to the language (similar to Figure 10-3 in Chapter 10). Both groups were told that the database consisted of six kinds of hypertext nodes (cats, dogs, boys, girls, men, women) connected by four types of links (parents, owners, likes, dislikes).
Step 1. Construct a Query. The language being evaluated still retained Phidias' query language structure. It had a syntactic category named “Query” (which no longer exists in the revised language). Thus, the first step when working in the language used in the Walkthrough is to realize that a Query must be constructed. This is the first piece of doctrine about the Hermes system and its language that is needed to create the list of people. Non-programmers (for whom this language is intended) may not be familiar with the term "query" as it is used in computer database jargon. They might not know that queries are the mechanism to search a database and return a list of the items specified by the query. In practical terms, this issue means that the user of Hermes must know how to find the menu option for constructing a query in the Hermes language. In the walkthrough, this corresponds to focusing on the language options for a Query in the syntax.
The syntax for Query is the following (Capitalized terms here are non-terminals further defined in the syntax. Note that this syntax included a number of operators that no longer exist in the language or that have different names as defined in Appendix C.):
disclose Article Relationship Preposition Article Subject which Filter as How, with their Relationship, if Boolean, else Query.
The walkthroughs emphasized several problems with this syntax. Interestingly, the problems pointed to were very similar in both walkthroughs, even though in the first sessions this syntax was displayed textually (as an explicit BNF formalism) and in the other session it was displayed as a dialog box with buttons for each term (for tacit direct manipulation). In both cases, the Query option was considered visually confusing in its overall impact as well as in some of its details. Above all, there were simply too many terms to deal with at once.
This complaint had several aspects. First, the number of terms was too great. It turned out that these terms fell into three categories: operative syntax options, glue words, and fillers. The syntax terms which represented computational mechanisms were the terms: Relationship, Subject, Filter, How, Relationship, Boolean, Query. The glue words were Article and Preposition, which could take on values of articles and prepositions to make queries read more like flexible English without changing the computational meaning—e.g., all arguments about those answers instead of just arguments of answers. The filler words were disclose, which, as, with their, if, else; they make the syntax more meaningful to the human reader, but play no role computationally. It was felt that the word "disclose" is unnecessarily obscure, and might best be replaced by something like "show" or "list", or be eliminated.
The glue words seem to just get in the way. They add unnecessary work, looking up their possible options, and they clutter the query statement. Operator options like Article and Preposition require an extra level of look-up in addition to the main language syntax options. While they add a marginal degree of smoothness to the reading of the query, they are simply in the way during the writing of the query. Moreover, they obscure the functional structure of the query, making it difficult to determine what is operational in the query and what is not. The other filler words are less of a problem because they do not require any action by the query formulator and they make the structure and function of the query clearer even during the writing stage. Nevertheless, it was suggested during both walkthroughs that a radical rethinking of the language (e.g., in a Lisp-style functional notation or in a visual programming graphical notation) might well do away with the fillers and lay the structure of the query bare. Here, the trade-off between supporting tacit and explicit understanding was already clearly coming into play.
Given the complex definition of the query, a programmer has little guidance on where to begin and how to proceed. The terms in the syntax template appear equally important. In fact, in this version of the language all of the terms are optional. Any subset of them can be defined in any order, giving the one template great generality and allowing it to stand for many possibilities. However, this gives little guidance to the programmer. It is not clear to a novice user how the system would compute a Query without a Subject, or one without an if Boolean but with an else Query. A more general problem is that there is little support for the person constructing a query step by step: where to start, what order to proceed in, what has been defined so far, how to test partial queries, how to re-use existing queries and already defined complex terms.
Step 2. Define the Subject. To build effective queries in a hypertext system like Hermes, one must begin by defining a Subject of the query that corresponds to the starting point of the search that is to be defined. For instance, in the query, arguments of answers, the computer will start with a set of answers and follow their argument links to the set of their arguments, which will be the result of the query. Similarly, in people that have more than 3 grandchildren, the system will start from a set of people and traverse links to discover which of them have more than three grandchildren. However, this was not obvious in either walkthrough. Both attempts went astray at this initial step. In the April session, analysis began with the grandchildren and tried to compute their grandparents (eventually getting stuck trying to trace back which of the grandparents had more than three grandchildren). In the August walkthrough, the idea that the Subject of a query like arguments of answers was answers seemed counter-intuitive. In fact, it seemed counter English-like. In English, "of answers" is a phrase modifying the noun (subject) "arguments".
Another way of putting the problem of choosing the Subject is that the user might assume that the Subject is that which is to be disclosed or listed. So, in arguments of answers, the Subject might be taken to be the arguments that are sought. In fact, however, the Subject of the query must be the answers, from which the search for arguments begins.
The walkthroughs fundamentally questioned the assumption that had been taken over from the original Phidias query language that the starting point of hypertext navigation corresponded to what people would naturally name as the “subject” of a query. The strategy of the Phidias language had been to model the language as much on the structure of English as possible. This strategy worked well for the readability of the language. However, the walkthrough began to uncover problems with the strategy when one wanted to write innovative expressions.
The people who originally used the Phidias query language would formulate a query like answers of issues with their arguments to instruct the computer to start at each of the issues and then list its answers with sublists of all the arguments of each of those answers. It was assumed that this was the "English-like" phrasing, and the query language’s syntax corresponded to it nicely. But consider the following equally natural requests for the same output:
* answers with their arguments of the issue.
* for each issue list its answers and for each of them list the arguments.
* each issue's answers and their arguments.
* arguments for each answer of the issues.
* arguments for each issue's answers.
It seems that any of the three operative terms can come in any position in English and that a variety of equally plausible alternatives are available for even the simplest queries. The users of Phidias had, perhaps, been accustomed to think in the Phidias programming language. The fact that this may have happened without anyone realizing that learning of a new language was taking place may speak well for the readability of the language, but it covered up the writability issues. The Phidias queries seemed "English-like" not because they represented the obvious way to formulate the queries, but because once formulated their meaning (semantics) seemed intuitively clear. That is, a query that would procedurally navigate the hypertext sounded like an English language description of the results that would thereby be produced.
What worked for the original Phidias language cannot work for the considerably more complex Hermes language. The Phidias language was syntactically limited to simple query statements. In fact, most queries formulated in practice instantiated a handful of patterns. Moreover, these patterns were part of a culture existing among the people who worked together on Phidias. The Hermes language, in contrast, is highly generative, allowing an unbounded variety of expression forms. While it is assumed that some training will be necessary for its use (in fact, considerably more than was given to the walkthrough participants), the language is supposed to be usable by designers in workplaces who have arbitrarily complex and innovative information retrieval needs.
A serious confusion arose in determining the correspondence between nodes or links and Subjects or Relationships. In the Phidias culture, a phrase like answers of issues corresponded to answer links coming out of issue nodes. The nodes at the other end of the answer links would, it was assumed, be answer nodes. In a standard Phi issue-base hierarchy this was a reasonable assumption. However, in the general case, a link of Type x might point to a node of Kind y. So the original assumptions of how node and link structures correspond to English descriptions and query syntax no longer necessarily obtain.
An issue also arose in the step of defining the Subject having to do with conjunctions. The Subject, people, had to be defined as a conjunction of boys, girls, men, and women. In ordinary English, one might say "men and women who ...." But the computer combines nodes using set operations, so one has to say "men or women who ...." Whereas a native English speaker would use "men and women who ...." to group all the men and all the women together, the computer would interpret this as people who are men and who also are women, i.e., the null set. The first aspect of this problem is that the query writer must leave tacit common English and think in explicit set terms; the second part is that the syntax options redundantly included and and or along with the set operations for union and intersection—and the relationships among them are unspecified.
A more general point that came up concerning the presentation of the syntax is that the overall structure is not clear. The syntax looks like an arbitrary listing of many possible syntactic templates. What are the important primitive (or first class) elements here and what are the rules for combining or abstracting them? If Query is a primitive object, can one request: disclose queries that ...? Are there general principles for combining Subject, Relationship, Filter, etc. that underlie the definitions of the templates? Is so, could these principles be given instead of the seemingly arbitrary proliferation of template options?
Again, the question of structure goes back to the tension between the English language perspective and the hypertext navigation perspective. The underlying structure of the language as a computer programming language for hypertext querying has to do with the structure of nodes and links in the hypertext. However, the appearance of the language is tuned to the rather different structure of English language descriptions of results desired, as stated using terms of the domain (grandchildren, answers, wardrooms). This tension became explicit in Step 3.
The list of syntax templates arose from a series of trade-offs. The Operator options allowed the collapsing of several language options into one: e.g., Subject and Subject, Subject or Subject, ... into Subject SOperator Subject. This reduced the overall number of options, but added another layer of options (SOperator) to go through. Another trade-off has to do with providing templates that correspond to common queries versus maximizing the generality of the options. Adding options increases the likelihood that a need can be met immediately without the extra effort of building up from several options or specializing from a complex, generalized option. The trade-off is that this proliferates options, making it harder to locate the correct one.
Step 3. Think through the computation process. At some point early in the formulation of a non-trivial query, one must focus on the computational process needed to get the desired results starting from the given information. For instance, given nodes for various kinds of people and links to parents, how can a list of certain grandparents be defined? In the walkthrough task, one must first generate a list of people by generating lists of men, women, etc., and then combining these lists. Then one must perform a mapping from these people to their grandchildren by crossing the parent links coming into them to get to their children and then repeating this to get to the grandchildren. For each person, the number of their grandchildren is computed and compared to 3. Those people who do not meet this condition are filtered out of the list of people, and the remaining list is the desired output. It may be useful to conceive of the sets or lists of nodes as "streams", and the computational process as consisting of operations on this stream such as generation, mapping, filtering, performing conjunctions, applying predicate tests, etc. (see Abelson & Sussman, 1985). Such an abstract scheme would provide a way of analyzing a task. If the language's syntax was organized this way, then the procedure of formulating a query might be more straight-forward. It is even conceivable that a query formulated on the basis of this scheme could then be translated into an English-like format to enhance future readability.
The point is that for any non-trivial query the writer will need to think through the computational process in terms of operations on nodes and links. For each operation, the writer will then have to select the proper syntax option. So the selection of query terms will be made on the basis of a conceptualization in terms of nodes and links, not directly in terms of domain concepts (answers, grandchildren, etc.). The domain concepts have to be translated into system concepts (i.e., into the terms according to which the hypertext database is organized) before the structure of a query can be determined. This implies that the syntax should correspond to the system view which the user must develop, rather than to the user's native English formulation of the task.
This consequence applies to the writing of queries, not the reading of them. If a query has already been stated in an English-like way so that it reads like a statement of the general task that it indeed carries out, then the user may not need to think in the system terms of nodes and links at all. This would relieve the user of a considerable cognitive burden and justify the approach of supporting tacit understanding.
However, even if one anticipates that the language will be used almost exclusively in a read mode by most users, one should not underestimate the concern for the language's writability. Both programming walkthroughs underlined the inadequacy of the "English-like" approach for programming queries, and the strongest implication of both was the necessity to redesign the syntax to reflect more closely a system view of computations. That is, there are important times when it is necessary to think in explicit computational terms and the language should support this as well as tacit readability.
Step 4. Formulate the query based on the computation. Once the necessary computation has been understood, the query can be formulated. A first step might be to consider alternative starting points for the computation based on the structure of the data. In the given task, for instance, both walkthroughs got side-tracked by following parent links from people to their grandparents. To complete the task, one must add up each person's grandchildren, which means following the links in the other direction to each person's children and to their children, so that each grandparent will be associated with the set of his or her grandchildren.
This raised a question about backwards links, called "converse" links in the syntax. It may not be obvious to users that links can be traversed in both directions. In fact in Phidias they could not be. So this is intended as a new feature in Hermes, and the converse Relationship option (along with its explanation in a User's Manual or training session) is meant to point out this possibility. In fact, the given task could not be performed without the ability to traverse links in both directions. However, even if one wants to retain this functionality, "converse" may not be the best term to use.
Once alternative strategies for achieving the task have been worked out, the programmer of the query might optionally try to estimate the relative computational efficiency of the alternatives. For instance, in the given task one might reason that only adults could have grandchildren. So, instead of starting from a set of people that included boys and girls, one might start from a set of people defined as men or women.
The analysis of the task in terms of defined nodes and links implies the selection of Subjects and Relationships. These must be built from the given kinds of nodes and types of links, using whichever syntax templates produce the desired results from the primitives. Thus, the Subject option, Subject SOperator Subject can be used to combine men and women with the appropriate connective selected from the list of SOperator options. Similarly, the best Filter option can be chosen by a pattern matching process: the option have COperator Number Relationship ... allows a numeric comparison, where COperator is matched to "more than", Number to "three", and Relationship to "grandchildren". Unfortunately, another option, have QOperator Relationship, also almost seems to match, necessitating extra analysis.
The walkthroughs uncovered a technical problem with having the user always choosing from lists of defined options. For instance, to choose a primitive link type the user selects from a pick list containing all defined types. The advantage of this is that spelling mistakes are avoided and long names can be entered with a click of the mouse. The problem is that the type must always be defined before it is used. This creates a problem in two situations: top-down design and recursive definitions. Suppose one wants to define a Relationship, issues and discussion, before one has defined discussion. In top-down design it makes sense to use a subcomponent before figuring out its definition in detail—as long as it gets defined before actual program execution. With the Hermes graphical user interface, one would at least have to define discussion with a simple, nominal definition prior to referring to it in a higher-level definition. (Then one could always come back later and refine the lower-level definition.) In the case of recursive definitions, one could not define discussion as: issues with discussion, because when one went to select the last term in this definition the Relationship discussion would not yet be on the list. This is a problem arising from the Hermes interface. In Phidias, the user simply typed any character strings into the command-line interface. Of course, one could work around this problem too by first defining a dummy discussion Relationship and then redefining it with the recursive definition.
Step 5. Test and refine the query. Ideally, one should be able to build up complex queries iteratively, testing as one goes. This was not possible during the walkthroughs because the Hermes language and its interface were not completely implemented. The interface should be designed to make the testing of query components as easy as possible.
In addition, the construction of modular queries should be supported. One should be able to define a Subject as men or women, save it with a name people and then subsequently use it in queries. Similarly, one should be able to define a Relationship converse parents of converse parents, save it with a name grandchildren, and use it later in the final Query:
disclose people that have more than 3 grandchildren.
This kind of modularity promotes top-down and incremental design. It also hides the complex details and provides building blocks for other queries in the future.
Finally, once the task is solved and the query has been shown to work properly, the user may want to check the appearance of the query for readability. In the above example, care has been taken to name terms like people and grandchildren with descriptive names in the plural, so they make sense and sound reasonable in the query syntax. Also note that the awkward and non-English-like phrases have been hidden within secondary definitions that are represented by these carefully chosen names.
The revised language. In response to the findings of the programming walkthroughs, an extensive redesign effort was undertaken. In particular, many of the “English-like” analogies of the original Phidias query language were eliminated in favor of a mixing of support for tacit and explicit understanding. The primary redesign decisions resulting from the walkthroughs are discussed below: 
Decision 1. Provide for multiple skill levels. The programming walkthroughs highlighted the problematic nature of writing expressions in the Hermes language. Experience using the language on more complicated tasks than that tried in the walkthrough suggests that, in fact, it would sometimes be easier to use a general programming language like Pascal or Lisp than to apply the Hermes language. This suggestion is closely related to the difference between the natural language model of the task and the node-and-link system model. That is, if one arranged programming tasks along a spectrum from trivial examples like disclose boys, through typical Phidias queries like answers of issues with their arguments, to more complex computations like display people that have more than 3 grandchildren, and finally to small applications like the academic advising example (Appendix B) used to test the unrevised language, or to even more complex computations (like the privacy critics in Part III), then they would progress from being easy in Phidias to being do-able in the Hermes language to being easier to do in a general programming language. The advantages of the ties of the Hermes language to natural language become less helpful and more of a burden the more one needs to concentrate on intricate computations at the node and link level.
At the same time, an expression in the Hermes language has the great advantage of being very easily understood by a reader (assuming it has been carefully programmed with that in mind). For a design environment that is not restricted to use by people trained in programming, this is a great advantage. Even for trained programmers, use and re-use are promoted by having expressions be self-documenting at the surface English level. Perhaps the best solution is to recognize that people defining complex computations will need to think explicitly in system terms and use programming skills, but to shield most users from these demands as much as possible. With this in mind, the Hermes language has been divided into a number of skill levels, defined in Chapter 10:
* novice: read-only
* beginner: entry and display of data trees
* intermediate: hypertext computations
* advanced: multi-media critiquing
* programmer: general programming language
Decision 2. Replace Queries and Subjects with DataLists. The biggest problem uncovered by the walkthroughs was the complexity of the syntax. This complexity was due primarily to two factors: the sheer number of syntactical options and the lack of an apparent organizing principle based on the computational structure. The first strategy for dealing with the complexity was to provide different levels of the language for users of different skill levels. This should help users to adjust incrementally to the language. The second strategy is to structure the syntax more clearly along computational lines. This turns out to have the additional advantage of reducing the number of options.
The hardest part of completing the task in the walkthroughs was the start up. This required the most knowledge of background doctrine. It was the most confusing; once one was started along the right track, the rest was much clearer. The determination of the computational starting point is the key—not an analysis of the English description of the task or of the desired results. The starting point is always a list of nodes (people, issues, etc.). Once this list is generated, the task is solved by successively performing a series of operations on this list. If one looks carefully at the syntax, one finds three inter-related terms for lists of nodes: Query, Subject, and DataList. A Query consists of the resultant list of nodes returned by a computation. A DataList is an arbitrary list of nodes, including Query results. A Subject can be a list of one node, all nodes of a certain kind, all nodes in the database, a DataList, a Query result (indirectly, as a DataList), or some combination of such lists. This is unnecessarily redundant.
The revised language eliminates the terms Query and Subject—two terms that caused considerable confusion in the walkthroughs—and consolidates their functions under the term DataList—a term that more clearly represents a system view of its role. The steps in solving a task are no longer to construct a "query" by first defining a "subject", but to compute a desired data list starting from some easily generated data list. The consolidation of these terms substantially lowers the number of options as well as clarifying their structure.
Decision 3. Require all parameters to be defined. Part of the confusion in defining Queries (and other terms) was that all their parts were optional and could be defined in any order. In particular, the main option for a Query (and hence the first one a user confronted) had ten terms, any combination of which could be defined in any order. So this first step offered the user several million permutations. The syntax had been structured with all terms optional in order to make each option as general as possible. However, it turns out that the syntax can be defined with all terms required, and the result is much greater structural clarity and simplicity with only a few more options. Compare a slightly cleaned up version of the old definition of Query (where the glue words have been eliminated and DataList has been used for Subjects, Queries and DataLists, for the sake of comparison) with part of the new definition of DataList:
DataList ::= Association of DataList that Filter as How, with their Association , if Boolean, else DataList
DataList ::= Association of DataList | DataList that Filter | DataList as How | DataList with their Association | if Boolean then DataList , else DataList
In the old definition each capitalized term is optional, in the new they are each required. The five options of the new definition allow one to build up a DataList through the same five operations that are combined in the old definition. The two definitions are formally equivalent because the old one can be converted to any of the new options by dropping optional terms, and the new options can be nested to build the old definition. But look how much clearer the function of each of the new options is. They each define a way of combining a DataList with another syntactical term (Association , Filter, How, or Boolean). Once one of the new options is chosen, there are only two choices: define the first term and then the second or the second and then the first. This new format makes the structure much clearer—for instance, it is now clear that the five operations can be performed in any order, whereas the older format gave the misleading and confusing impression that there was a required order. In fact, exactly the same operations are generally needed regardless of the template formats: to define people that have more than 3 grandchildren, one must press the same number of interface buttons in either version.
Decision 4. Eliminate glue words. The articles and prepositions have been eliminated from the syntax. They may have made sense in the simple, intuitive days of the Phidias query language, but they seemed to get in the way excessively in the walkthroughs. Above all, they obscured the structure of the computations being defined and added to the confusing appearance of the syntax. Too much smoke and mirrors.
Decision 5. Retain filler words. The filler words (of, that, as, with their, ...) have been retained in the syntax to aid in the comprehension of the options as well as increasing the readability of the final expressions. "Converse" has been replaced by "inverse", which is probably more colloquial. Disclose, which used to start all Queries, has been deleted, along with the troublesome terms Query and Subject. These decisions reflect a continued commitment to maintaining the readability of the language. The suggested alternatives of a Lisp syntax or a visual programming approach are not attractive. Lisp requires enormous doctrinal knowledge and cognitive strain for the sake of a somewhat more functional notation. It is not clear that a visual programming approach could retain the functionality of the Hermes language syntax and still improve its clarity or simplicity. One could easily change the appearance of the options from their English-like format to a functional format, for instance:
DataList ::= Association(DataList) | Filter(DataList) | How(DataList) | Association-sublist(DataList) | Boolean(DataList1, DataList2) | UnionOp(DataList1, DataList2)
DataList ::= Association of DataList | DataList that Filter | DataList as How | DataList with their Association | if Boolean then DataList, else DataList
However, for the non-programmer the filler words make the functional relationships much clearer.
Decision 6. Compress syntax levels. The Operator options had been created to consolidate options like DataList and DataList, DataList or DataList, etc. into DataList UnionOp DataList, where UnionOp ::= and/or (unique sorted union) | and also (intersection) | but not (difference) | or (append). This makes sense where UnionOp is used in several places in the syntax. However, the Operator options themselves proliferated, making it difficult to look them up, let alone remember them. In the new syntax, a number of these Operator options have been combined, eliminated or moved back to the higher level options in order to lessen the number of steps involved. Note that the use of "and" and "or" has been tied to the set operations in order to clarify the sense of their computation. The net result of all the changes to the syntax is a significant decrease in the number of options, despite an increase in the clarity of their computational structure, in their ease of use, and even in their functionality. Compared to the previous language, the revised language has only 12%, 55%, and 76% as many options in its Beginner, Intermediate and Advanced versions respectively.
Decision 7. Clarify the computational structure. The Media options of the revised language provide the primitive node contents. The Language options are functions that take a DataList of nodes and return a DataList of nodes. In particular, DataList options generate lists (streams) of nodes. Association options (and their subsets, InputAssociation and Predicate options) provide mappings of each input node to output nodes (based on navigation of links coming out of the nodes). Filter options are conditions applied to filter nodes out of a stream. Most of the language options define rules for combining options, the majority of which are forms of application with different semantics, like Association of DataList and DataList with their Association that both apply the Association to the DataList but return the resultant lists structured differently. In this sense, the new syntax is based on a computational structure, but is displayed in an English-like format. The English-like format is arbitrary for the writing and internal representation of the language (except that it may help the programmer remember the semantics), and merely plays a role in the display (readability) of the language.
Note that many options in each category are defined in terms of options from other categories. All options are stored in the hypermedia and can be referenced by the language itself (see the definition of ObjectType). In many ways, the revised language has some of the characteristics that make Lisp useful: it is functional, it is interpreted, and it can treat data as programs.
Decision 8. Improve graphical computations. The treatment of graphics was sketchy and awkward in the language. For instance, to test if a chair was near a table, one could define a Boolean as: ((Measure) of Graphic) is COperator Number, or: minimum distance to the table of the chair is less than 3. In the new revised language, one can first define a measure, closest distance is less than 3, and name that near. Then one can use that term in the Boolean: Graphic is Measure Graphic, yielding: the chair is near the table. One can then go on to define the kind of Boolean required for graphical queries: most chairs are near at least one table. This new syntax has several advantages: users can define their own terms for Measures like near, the syntax for the graphical Booleans is clean, and the expression is smoothly readable. By defining measures in terms of either central distance or closest distance, using the full range of quantity operators, and allowing quantification of both graphical terms, the graphical booleans provide for considerable computational flexibility.
Decision 9. Retain safeguards against errors. The language used scrollable pick lists for choosing Types, Kinds and defined terms. This protected the user from typing errors and from entering undefined terms, as well as reminding the user what terms or options were available. The only keyboarding allowed was to type in names for new terms. This prevented a variety of kinds of user errors that would have required debugging—perhaps the hardest skill to require of a non-programmer. In order to allow recursive definitions of Associations and Input Associations, a recursive self option was added to the syntax of these terms. Now if one defines a Relationship as issues with their recursive self and then names this discussion, the Relationship will automatically be made to read issues with their discussion. Similarly, the syntax for Input Associations is entirely designed to protect the user from error. Input Associations are intended primarily for data entry; otherwise they are just instances of Associations. The reason for distinguishing them is that not all Associations make sense for data entry: i.e., it makes no sense to apply Filter operators to nodes that have not yet been input. Only those options that are meaningful for input are included in the syntax for Input Associations and only Input Associations can be used by the interface mechanisms that prompt the user to elicit sequences of input.
Decision 10. Support the construction of language expressions. The new user interface to the language provides dialog boxes in conformance with the Windows 3.1 conventions. For instance, if one wants to create a DataList, one brings up a dialog displaying all the syntactic options for DataLists. In a given option, each term that has to be defined is represented with a button. Clicking the mouse on that button brings up a dialog with the relevant options for that term. Primitive terms like link Types are chosen from a pick list of defined terms. Dialogs are modal, so that work on a given dialog must be completed (or canceled) before reverting to work on a previous stage. As an expression is built up, it is displayed at the bottom of the dialog box in its English-like format. Control buttons are available on most dialogs for naming and saving a constructed term, for bringing up and editing a previously saved term, and for changing the interpretive context in which terms and expressions are defined. The dialog for DataLists also includes buttons for evaluating the DataList (testing it) and for saving the results to disk (for subsequent processing or viewing).
The construction of expressions in the Hermes language could be supported with a wide variety of other mechanisms beyond the scope of this research. One could have graphical palettes of previously defined expressions, browsers of the hypertext structure, intelligent assistants that suggest new constructions or critique partial constructions, facilities for specifying desired results, checklists for steps to be done, and context-sensitive help. Some of these have been tried in Modifier (Girgensohn, 1992). It is hoped that defining expressions in the Hermes language is generally not so difficult as to warrant such extensive support. As Girgensohn implied, the supports he developed were largely required because of a non-intuitive representation of critic definitions, etc. in terms of Lisp expressions and property sheets. Although it is likely that certain forms of support, carefully designed and implemented would be extremely useful, Girgensohn (1992) probably turned to providing such supports too early. The Hermes language is carefully designed to provide representations of useful computations for design environments that syntactically support designers tacit and explicit understandings.
Decision 11. Provide training in the use and extension of the language. The walkthroughs made explicit the background doctrine that is required to write expressions in the Hermes language. Clearly, some instruction is needed to explain the purpose, format, implementation, and use of the language to new users. This instruction must include some discussion of navigation and computation across hypertext, as well as a description of the syntax, semantics, and pragmatics of the language itself.
During the year since the development of the revised language, the Hermes language has been further refined to clarify its structure, functionality, and appearance. Its current design is reflected in Chapter 10 and Appendix C.
 A BNF of the current Hermes language can be found in Appendix C. The version used for the Walkthrough had a similar structure, but many of the terms used in that language and discussed in the present Appendix have been changed, primarily as a result of the Walkthrough. These changes may cause some confusion in reading the following discussion.
 It should be noted that the Hermes language continued to evolve after these revisions, so that the syntax in Appendix C and the examples throughout the dissertation do not correspond exactly to the revised version of the language discussed here.
Go to top of this page
Return to Gerry Stahl's Home Page
Send email to Gerry.Stahl@drexel.edu
This page last modified on January 05, 2004