Friday, February 25, 2005

MathML Experiment

This is a sample of MathML embedded in a post:

Presentation MathML:


x=



-
b

±


b
2

-

4

a

c




2

a





Content MathML:




x




±



b







b
2



4
a
c


0.5




2
a




x=\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}


x={-b plusminus sqrt {b^2 - 4 ac}} over {2 a}

What's up with the microfocus on side-effects and atomicity and stuff?

(Originally published on: Wed 17 of Nov, 2004)
I’m interested in creating high-leverage techniques for transforming and composing sets of models to significantly advance the capabilities of the Model Driven Architecture (MDA) approach to software development. I intrinsically believe that the first step in this process is clarifying the formal foundation on which model transformation rests; in particular, clarifying and formalizing notions of context, atomicity, concurrency, complexity and performance in order to be able to more accurately determine whether two models are equivalent and whether one model is superior to another in certain desireable domains.

I believe a useful starting place to begin this work is to examine the theory of formal mathematical functions and (possibly) extend it to provide some additional tools for analyzing the types of functions found in programming languages. (For this purpose, I have begun by considering proceedural programming languages, since they are most prevalent and often least served by formal analysis. I’ll extend the thinking to declarative, constraint-based and other forms of programming languages as a secondary activity.)

What I’ve been chewing on for most of this last year is how to effectively broaden the bridge between formal mathematics and various computer science constructs in a way that really facilitates this analysis without needlessly inventing new concepts.

Most of the conceptual tools we need already exist to one degree or another, but they are often found in unrelated or informally related domains. (Lots of transaction work has been done from the point of view of databases. Very little has been done to bridge that work to the work done on conventional procedural languages.) I'd like to clarify a context in which these concepts can be brought together, transformed if necessary, and assembled into a powerful and useful toolbox for understanding what is possible and semantically correct in model transformation in the general case.

Applications, I/O's and Side-Effects

(Originally published on: Wed 11 of Aug, 2004)
Scott sent me an incredibly timely reference: "Computation Beyond Turing Machines" by Peter Wegner and Dina Goldin, April 2003/Vol. 46, No. 4 COMMUNICATIONS OF THE ACM.

The gist of their thesis is: "In each case, interaction between the program and the
world (environment) that takes place during computation plays a key role that cannot be replaced by any set of inputs determined prior to the computation."

This directly connects with thinking I was doing this morning on side-effects and models of computation. What originally started my train of thought was the observation that while functional models of computation are commonplace, they are seldom used to model entire applications. Usually, they model a single function and its data-in/data-out transformation.

However there is no reason why functional models can't be applied to represent the behavior of an entire application. Doing so brings up two interesting things to consider.

First is the state-space of the inputs. The state-space for a relatively trivial application (like a word processor) can be nearly infinite. This makes it much more difficult to quantitatively state the range of the application in terms of operations on its domain.

Second is the fact that most applications have changing inputs during the course of execution, which is at odds with the standard functional model of outputs as a function of initial conditions.

Tackling the first problem can be done using fuzzy computation and isomorphisms. It is possible to reduce the statespace of the inputs by considering only the inputs relevent to the computation to be performed rather than all possible values.

Second, my observations from this morning illustrate a model for beginning to map interaction into a functional model....

TBD...

One person's side-effect is another's parameter...

(Originally published on: Tue 10 of Aug, 2004)
I've been puzzling for some time over the role of side-effects in the design and development of software systems. There are a number of different flavors of side-effects in common usage, but they are most often encountered in the form of global variables.

Most competant programmers abhor global variables by tradition and bitter experience. However I've been pondering lately whether globals are terrible by nature or if their problems are an artifact of implementation.

So, what are the attributes of a global anyway? Are all globals bad or just some kinds?

Let's see...

There are static constants. What's wrong with them? Not much, except that global constants declared in separate packages can conflict, either causing compile-time errors or masking each other and causing unexpected runtime errors.

So, namespace is an issue. Specifically, the conflict between the desire to have a global namespace full of well-known entities and the desire to assemble it incrementally by composition based on input from an arbitrary set of packages that have no particular knowledge of each other.

How about global variables?

There are a number of problems typically associated with global variables, most of which are variations of one basic problem. Because the variable is global, its value can be set or read at any time from anywhere within the global scope of the system. This manifests itself as a problem with:
  • Initialization
  • Finalization (memory leakage)
  • Lost and unexpected changes (race conditions)
  • Hidden dependencies (inability to compile or run extracted code fragments)

It is interesting to observe that both of these problems are addressed at length in other contexts. Namespace normalization and integration is widely tackled in the areas of schema integration and metadata management. The issue of race condtions surrounding access to a global is tackled by both concurrent programming groups and database engineers under the general banner of transactional or monitored access to shared resources.

Why the techniques used in these other application areas haven't been rolled back in lightweight form to improve the usefulness and safety of globals is a question I'll come back to another day. For now, it's interesting to consider the last variant problem: hidden dependencies.

Hidden dependencies commonly happen when one block of code sets a global variable under certain circumstances and another block of code reads and acts on the values of the variable in specific ways. If the first block of code changes its behavior, the second block of code may break in surprising ways. In fact, a block of code can break itself if it both reads and sets the global in an inconsistent manner during its execution.

In theory terms, what's happening in the first case is that the range of one function and the domain of a second are interlocked but there is no explicitly declared definition of the domain or range of either so it is extremely difficult to disentangle them. When considered strictly from an API perspective, both functions really have an imaginary parameter as part of their signature.
r1i = f(a, b)
r2 = f2(a, b, i)

This can also occur with local variables, when a single block of code first changes and then refers to a variable during subsequently executed lines of code. (In this case, the function's range is folded back so that it's domain interlocks with it and the function has an implicit self-dependency.) In practice, this is seldom considered to be a problem unless complex procedural logic like recursion is encountered, or if the state of the variable persists across invocations of the function.

So this leads to what I've been pondering about side-effects...

Something is an acceptible behavior if it is explicit, has a contractual definition and is introspectable. Otherwise, it is generally considered to be a side-effect. All of these characteristics of global variables that I've been talking about are well-mannered behaviors when they occur in other forms (databases, shared resources, etc.) because in those forms, the behaviors are complex enough, and occur frequently enough, that programmers are willing to spend the effort to codify contractual and introspectable definitions around them.

In the case of plain old global variables, however, they are generally used in situations where simplicity and speed of development are desirable and their implications are frequently not well-thought-out.

So that kind of leads me to the question: are there other ways to provide the benefits of explicit contractual relationshps around globals without having to force a heavyweight, design-intensive experience on the developer? Possibly by embedding the analysis in code refactoring tools rather than in runtime mechanisms?

The Dining Philosophers Club has moved

The Dining Philosophers Club was originally implemented using TikiWiki. This proved to be a frustrating choice. TikiWiki's overabundance of features and relative immaturity made it an ongoing burden and the inability to use MathML for posts containing equations was a final blow.

We will see if Blogger proves to be a better solution.

I will migrate my few previous posts to start things off and then dive into new material. I've been working on a Java-based standard three-tier app for the last few months (for an odd change) and I've started developing some thoughts on structuring web-based applications.