This document is intended to gather into one list a lot of the major redesign issues that we had problems with in the most recent version of the Aesop system. My hope in providing such a list is that we'll be able to consider these issues early enough in the design that we'll have better success at dealing well with them.
For each issue, I've added a description of what the problem is, a description of what resolution we've come to, if any, and a categorization of the problem into one of the following categories:
At one time, it seemed to me that the ABLE group didn't have an agreed-upon definition of what exactly a software architecture is.
I now think that I have a better understanding of our consensus of software architecture. In particular, we can focus on the following definition from the IEEE Transactions on Software Engineering's Special Issue on Software Architecture:
The structure of the components of a program/system, their interrelationships, and principles and guidelines governing their design and evolution over time.Note that that description, like most definitions of software architecture, blurs the lines between architecture and style somewhat, since the `principles and guidelines' might reasonably be said to be part of the style, instead of part of the architecture. But this is is a good start.
2. What is Architectural Style?
Classification: Domain Analysis
At one time, we didn't have a clear notion of what architectural style was, we just knew that `style' was what Fable environments were supposed to manipulate.
We've made a lot of progress on this question in the week of June 12-16. We've come to the notion that a style is a set of architectural designs, and nothing more. An environment, then, is based on a style and a set of policies; an environment is constructed to support the chosen style and set of policies.
This is a little odd to me, though, because it it suggests that style is a completely static property. For example, this definition would not capture the notions of `top-down' or `bottom-up' system design, in which the same designs are possible, but they are arrived by different paths.
3. What Type System do we want?
Classification: Requirements Analysis
We've completely bought into the idea that designs should be represented by object-oriented structures, and that modifying or analyzing designs should be done by invoking methods on objects.
However, it hasn't always been clear what sort of type system and object hierarchy we want. In particular, it hasn't always been clear exactly what the relationship is between, say, a component and a filter.
We've figured out some things:
The key is this: an object's type is determined only by the behavior of its basic methods. Therefore, if two specifications of the filter type exist, such that the specifications differ only in that one has a `normalize_ports' method that can be implemented in terms of AddPort and DeletePort, then those two definitions of filterness are in fact equivalent, and objects of the two types can be freely interchanged.
Even so, I'm not sure we have perfectly defined our type system yet. In particular, we've been fudging a bit on the mechanism for downcasting.
4. Get MVC Working Properly
Classification: design problem
According to our notion about how things should work, designs are stored in the database. Visual representations are not stored in the database; they are generated in the user interface, such that at all times, they merely reflect the information stored in the database. (They may also be used as mechanisms through which the design in the database can be manipulated.)
This is known as the Model-View-Controller paradigm. The design in the database is the model, which carries the underlying `reality', and the visual representations are views of the model.
In the design, we didn't do a good job of fulfilling that ideal. There are two families of objects stored in the database, the CFamObject family and the CVisObject family. There is cross-over and contention about which of the two families should dictate to the other. We should improve this.
One test of our ability to do this well is that we should be able to have two copies of the user interface open on the same design at the same time.
5. Get Undo Working Properly
Classification: design problem
We have a reasonably strong notion of what we want from an undo command. (There are some tricky points associated with integrating an undo mechanism with the transaction mechanism of the database, and its not wholly clear how one should undo an action that is implemented by multiple tools.)
Undo is a tricky thing to get right, though, particularly when it's not designed into a system from the beginning. Particularly if we want multiple levels of undo (which I think we do) it behooves us to consider those design problems from the beginning. Undo is not a trivial extension.
The Gang of Four Design Patterns book has a few patterns that are useful for building undo; it would be worthwhile to look at those.
7/21/95: John Ockerbloom pointed out that since we're using multiple programs and processes to implement our changes, undo has the flavor of requirements analysis, because it's not clear what undo should mean when actions are handled by multiple tools.
6. Heterogeneity of Styles
Classification: Domain Analysis, Design problem
I suspect that in the Real World (tm), relatively few designs can be simply decomposed in a single style. Therefore, to make our system useful, we will have to figure out how to manage designs that borrow from different styles.
Some of the things we need to handle with the Aesop system, in order of increasing difficulty and decreasing necessity:
Currently, bindings are simply assertions of equivalence. In order to bind two ports, say, the two ports must be identical.
This could create problems for heterogeneous styles, as mentioned above. For example, if the outside port on a component is an output port in a pipe and filter system, and the internal representation of the component is in a style that knows nothing about output ports, how can the binding bridge the gap between the two ports?
8. Separating Styles, Environments, Policies, and Types
Classification: Requirements Analysis
This issue has gotten somewhat resolved as a result of the clarification we've done on the question of `What is a style?' (v.s.)
We have a notion now that a style-specific environment is created from a definition of a style (as a set of designs) and a policy that specifies how the environment should respond to various exceptions.
I'm not sure, though, that we have a clean distinction between policy and types, and I'm even less sure whether we have a distinction between policy and classes.
We do have a planned mechanism of `pre-checks' and `post-actions' on each method, and this is progress. I think we're converging to a position that says that types define exceptions that can be generated by methods, and policy defines how those exceptions are treated.
9. Tool Interfaces
Classification: Design Problem
This may be less of an issue than it once was, because we are trying to switch to a notion in which tools are merely a mechanism for implementing methods on objects.
Since I wrote that previous paragraph, we introduced a notion of `agents', which would be tools like the user interface that present a different abstraction to the user; these are more like interfaces to the database objects than they are methods on the objects.
We then realized that `agents' were what we had previously been calling `tools', so we changed the name back to `tools'.
We still need to decide in detail what the interfaces (connectors, if you like) between these agents and the rest of the system, particularly the database, are.
It would be desirable to have a simple and consistent interface for agents. It would also be desirable to have an interface that worked and served our needs.
At the moment, I'm not sure we even know what our needs are. It would help clarify our thinking to populate the space of agents a bit.
10. Design Rules
Classification: Design Problem
`Design Rules' are the rules that are enforced by style-specific environments. We have a notion of implementing these by pre-checks and post-actions on methods, but I'm not sure we have a coherent scheme that accounts for all the ramifications:
In particular, sometimes we have checks that aren't easily localized to one particular object. Are we sure that every rule we can imagine can be considered a property of one object?
Furthermore, some rules should not be enforced all the time. Some requirements should be checked only occasionally or even only checked when the user asks. Do we have a viable scheme for making sure that checks are done when needed, if `when needed' is not `at every relevant action'?
11. To Stay with Fcl?
Classification: Design Problem
For Aesop II, we used Fcl, which is Tcl plus an interface to the Aesop database plus an object/class system. Do we want to keep using this, or change to something else?
The primary virtue of staying with Fcl is that we can customize the method dispatch and type system of Fcl to be what we want them to be. This is good. There are also some conveniences to using an interpreted language for our purposes.
The bad side is that Tcl provides very little help for structuring data, checking type safety, and so forth. Furthermore, our implementation is terribly slow. This is bad.
I'd suggest that we probably do want to stick with using Tk for our GUI. But that doesn't require us to stick with Tcl, since Tk has been ported to other languages. Drew is very enthusiastic about Scheme/Tk, for example.
To make this decision well, we need to look more closely at how much code we will be able to reuse, and what pernicious problems Fcl gives us, and how much we are willing to put up with them.
What is the expected role of ACME in the Aesop system?
I'm not sure that this has been clearly thought out. Is ACME just an export language, never used for internal representations? Is the connection between the Shelf and the UI talking ACME? In short, what do we plan to use ACME for?
13. Design for Future Research
Classification: Requirements Analysis
What new areas of research do we expect to do? Will they be easy to implement and explore in the Aesop system?
From the software engineering course that I TA'ed, it seems plausible that that's actually not a very useful question to ask--it's almost certain that we'll go in a different direction than what we expect. The most important thing, then, is to build a clean, coherent system, so that it is easy to maintain and extend--because we will end up extending it.
14. Sort out the role of the shelf
Classification: Design Problem
As I understand it, the UI and the shelf are currently deeply intertwingled. They share some state through global variables, and would be somewhat difficult to separate into different processes. It's also not clear whether the depiction of the shelf as being connected to the event system is really accurate.
If our goal is to separate the UI and the shelf (it was, once), it's probably appropriate to think a bit more about what the role of the shelf in a design environment is.
I've raised the idea that perhaps the shelf is a separate agent. The major advantage of this notion is that it raises the number of agents we keep in mind to two. :-) The other advantage is that in our ontology of Fables, every component is either a tool or the design database. The shelf is certainly not the design database, so if it is not a tool and we want to represent it at the top level of the Fable, what do we call it?
On the other hand, we also had a notion that the palette and the shelf are logically equivalent, with the only difference being their size, scope, and browsing mechanisms. Perhaps, then, the shelf should be a part of the implementation of the UI, the way the palette is.
In light of this, I've changed the name of this topic from `Make UI and shelf wholly separate' to `Sort out the role of the shelf'.
Currently, we only store data about design objects in the database. We store nothing of the definitions of types, the definitions of methods, the hierarchy of classes, or anything of the sort in the database.
This gives us problems sometimes. In the first place, it complicates the problems of dynamic loading of class definitions. This will become more of a problem as we sort out the issues of heterogeneous styles, and as we increase the number of types about in the world.
Furthermore, I firmly believe that we will want some objects that modify their behavior somewhat in ways that don't apply to the whole type. For example, Darrell Kindred found that gzip is a filter with constraints on its applicability--we might well want to represent these constraints without creating a CFamGzipFilter class. Currently, we have no way to represent per-object behaviors.
A modest proposal:
Let a design refer to a style, which refers to a set of type definitions that are included by default in every design in that style. Objects in that design that aren't of one of the types supported by default need to supply their own code. Thus, if you import a filter into a design in the generic style (and you keep it a filter instead of promoting it to a generic component), the definition of a filter would be stored with the object in the database.
Currently, don't have different types for .c files and for .fil files in the Unix-pf style, for example, even though they have somewhat different behavior. Some thought about what different types of representations we need would be in order.
At present, some things in the element workshops happen immediately, and some happen only when the workshop is closed. Being consistent would be nice, and that involves figuring out what we want.
The UI allows you to have multiple objects selected at once. This is nice, but it does create problems. The behavior of clicking on the 'port' button in the palette when you have multiple components selected is a bit strange, for example.
We have talked often about being able to certify an object as being a member of a subtype. For example, a component with only input ports and output ports could be certified as a filter, after which time it would behave as a filter and all filter analyses would be permitted on it.
This is a good idea. I look forward to being able to do this. But so far, we have handwaved over the details, and we can't do this forever.
It would be nice (and necessary if we're going to keep Drew from screaming) to use the database to store persistent objects, and also have non-persistent objects that encapsulate windows, visual objects, and similar things that should not persist beyond the lifetime of the system. Currently, we just store those objects in the database too, or we don't represent them as objects at all. Neither is very nice.
In the process of preparing the system to be released, we came across
an anomaly with trans
. Consider the following code:
while { trans { break } }In the previous implementation of
trans
,
trans
would turn the break into an error. Similar
problems happend with return and continue. That seems wrong; we
changed the behavior to pass the break through unchanged, and commit
the transaction. It's far from clear what the right behavior is,
though--should it commit the transaction?
Furthermore, the behavior of abort
within a transaction
that is within a catch
block within a trans
block is a bit strange, because the outer transaction gets aborted,
but the flow of control ends up ouside the catch. i.e., consider this
code:
trans { catch { trans { # aborts both transactions abort; } # control ends up here } }Actually doing this right will be hard without nested transactions, so we should think carefully about how we want to do it wrong.
We're not getting our full use out of Exodus' capabilities in the current version of Fcl. This includes several problems:
Aesop lets you have multiple aggregate representations on an object. This raises some problems of what it means to have multiple aggregate representations of a design element.
In particular, what should a tool like Build-PF do with multiple representations of a design object? This is a subtle and tricky problem, and I don't pretend to have ideas of possible answers, much less an answer that I'm sure is right.
It's something of a cheat to include this here, since this isn't so much a design issue to solve as it is a major research topic. But this ties in closely to the problems of multiple aggregate representations that we mentioned above. And you could easily imagine wanting to represent aesop-in-aesop with two related designs, one of which showed the code structure and one of which represented process boundaries.
Currently, we have nothing but the most vague and inchoate notions of how to solve this. Fortunately, we can probably build Aesop III without solving this, as long as we recognize that we are not solving this problem and do not intend to.
This is another cheat, but hey, if you're going to include one heavy research problem, why not include more?
The issue here is that some large-scale properties of systems deal with dynamic properties. For example, if components are being created and deleted dynamically, the issue of which components create which components can be extrememly interesting and important.
It can also be very hard to represent and deal with.
As of 6/20/95, we have committed to not coping with this problem with Aesop III. This is firmly out of our purview, unless someone gets a brilliant idea on how to handle these problems.
(I originally named this "Caching Checks", just for the pun value.)
We would like certain checks and attribute calculations calculated only at need or on demand. For example, a lengthy check that is required as a prerequisite for code generation should only be calculated once, if the code generation is invoked from a menu immediately after the check is done from the menu. However, if the design is changed, running the code generation should run the check.
We need to design a framework that makes such checks easy. In particular, it should not be necessary to rewrite the code to check whether an attribute is up-to-date for each new type of attribute.
Here's a thought: make
actually handles this problem
pretty well. Before we reimplement the square wheel, we should think
carefully about what we want, and to what extent a mechanism like
make can achieve our goals.
The filter language we have now is pretty pathetic. It has no way to close streams. It doesn't even have a while statement, or multiplication, or several other things. It would be very hard to use it to write a useful filter.
On the other hand, it's not clear how much a useful filter language would improve the quality of the Aesop system. This is particularly true in light of the licensing issues about distributing Synthesizer Generator programs.
My leaning is towards leaving the filter language as it is, even though it is nigh useless, or letting an independent study design a better filter language. But we shouldn't sink time and energy into this unless it's going to be worth the effort to do it right, and I don't think it will be.
This one should be pretty easy. We need a consistent, reusable way to highlight errors found by checks. The current mechanism used in the real-time style is just an ad hoc approach. A way to update Visualizations based on values of their objects would be terribly nice for this and other reasons.
29. The Style Developer's Tool
Classification: Domain Analysis.
Date: July 21, 1995
There are a bunch of currently open questions about the Style Developer's Tool. Each of these is significant enough to merit a heading as a design issue in its own right.
29.1 How Do We Describe Styles?
i.e., what notations and structures do we use to describe a style at
an abstract level?
29.2 How Do We Store Styles?
29.3 How Do We Transform Style Descriptions into Code?
29.4 What Sanity Checks can we do on Styles or Environments?
This one is really domain analysis in a big way.
30. Using Aesop as an Architectural Browser
Classification: Requirements Analysis / Design Problem
Date: July 22, 1995
This is one of David's pet ideas. He would like to be able to use the UI to build an `architectural browser', suitable for use on the Web and so forth. It's not wholly clear to me just what formats David is expecting, and how much he wants to be able to do with such a browser.
31. Architectural comments and "Post-it notes"
Classification: Requirements Analysis
Date: July 22, 1995
David mentioned an idea of being able to add annotations or notional `post-it notes' to an architectural design.
Again, it's not very clear what this would entail. It is true, though, that our graphical browser does not allow the same flexibility of locations for comments as that offered by most programming languages.
32. Patterns and Unification
Classification: Requirements Analysis / Design Problem
Date: July 22, 1995
The idea of adding support for design patterns into Aesop has been my research focus for a while. I've been pursuing an idea of being able to `unify' elements of patterns into a whole design. I think that in the last few months, I've come close enough to defining the theory of unification that I want to support in Aesop that it's reasonable to add that to the list of new features for the redesign.
But we should, of course, design in a modular enough fashion that it's easy to take out or modify this capability if it turns out to be a Bad Thing.
33. Visualizations
Classification: Requirements Analysis / Design Problem
Date: July 22, 1995
On July 6, we decided that somewhere in the description of an environment, there would be a description of visualization information for each type in a language suitable for each agent.
That's all right as far as it goes, but we still need to decide what sort of language we're going to use to describe visualizations to the UI agent.
34. Reuse of Styles and Types
Classification: Domain Analysis
Date: July 22, 1995
It's very important that we be able to reuse definitions of styles and types from one environment to another. However, we haven't yet thought much about how one indicates such reuse.
I see three major possible schemes of reuse; there are probably others:
Date: July 22, 1995
This is another big domain-analysis problem that we are not planning to handle with Aesop III. Here's the problem:
Consider a client-server system with one server and thirty identical clients. The fact that there are thirty clients is important for the design, particularly for the server. But a star with thirty points, each of them a distinct component, is not the best way to represent this design. Somehow, you need to capture the fact that these thirty clients are the same, as are the connectors between the server and those clients. This is not something Aesop can currently do.
For an example that's perhaps even more difficult for us to handle, suppose that the number of clients is not known--users might add or remove clients without restarting the whole system. (This ties in with the `dynamic architectures' issue above.
36. Handling External Files
Classification: Design Issue
Date: August 3, 1995.
The way external files are handled is not very consistent. In particular, it's not clear whether filenames should be stored as relative paths or absolute paths. Relative paths might be easier when we ship the system with design files, but absolute paths might be easier when one design is being used by multiple users at the same site.
ralph@cs.cmu.edu