Re: OO versus RDB

[Note that I'm just picking out interesting things to talk about. I
could care less about the thread to this point, nor the particular
definitions in use; and please feel equally free to ignore me.]

Marshall <marshall.spight_at_gmail.com> wrote:
> > Definitions are important; that's why we
> > have so many bunfights in these newsgroups about them.
>
> No. *Agreeing* on definitions is important; the specific definitions
> themselves are unimportant.

There is one commonly missed sense in which definitions are quite
important. Definitions that occupy common words (linguistic real
estate) and express concepts that are not fundamentally interesting are
harmful.

No outright disagreement, but I'm not sure what standard of "useful" is
being used for #2, or in what context. Useful is a matter of degree.
This harkens somewhat back to your question about which "side effects"
are important, and which are not. If the write to the variable affects
whether the program produces correct results (i.e., is "important"),
then it complicates the model similarly to any other write operation.
The model of the language now needs to contain some concept of time (or,
equivalently, state). That's a big deal. If that's not true, then of
course it doesn't matter, and you just need a way to let your tools know
that (and if the "tool" is your brain for the current task, than that's
presumably trivial).

So (I'm working this out as I go; please excuse any errors, and please
point them out...) in the interesting case, the time aspect of the model
is most flexibly expressed as a set of statements of the forms:

P(a,b,C): if expression b is evaluated , then a must be evaluated

before b with no intervening expressions in C.

One can write rules for the time dependencies introduced.

For general-case functional subexpressions (or functions under
applicative order), P(a,b,0) [0 is the empty set] if a is a
subexpression (argument) of b.

And for shared state, P(a,b,C) if:

(1) a writes state s(a) to a shared memory slot
(2) b reads from the shared memory slot and expects to find s(a,E).
(3) C contains all C[i] that write s(C[i]), where it is not provable
that s(C[i]) = s(a).

Knowing that the function (called f from here on) doesn't depend on
anything except its parameters means that it will never occur in the
"b" position due to shared state; which means that if P(a,f,C) then this
is a time constraint due to applicative order, so C is the empty set.
However, note that f can occur in a P(f,b,C), and also that it may occur
in some set C for which P(a,b,C). Sure, that's a useful thing to know.
If all functions worked that way, then in fact you'd be looking at the
same situation as applicative order again. If only some functions work
that way, then what the statements that can be made are relatively weak,
since two out of three ways for f to exist in a complex ordering
constraint to exist are still applicable. On the other hand, if f
neither depends upon nor modifies any "important" state, then we are
guaranteed that f only occurs in constraints for which C is the empty
set, which leaves a lot more room for manipulation.

Admittedly, the above is a horrible, inexcusable simplification, because
it fails to account for functions that both depend upon AND modify
shared state. When they get added in, your mutation-only function will
start to look a lot more appealing. The s(a) expressions above will
become s(a, ENV), and you'll be able to assert that for mutation-only
functions, s will be independent of the ENV parameter, and that will
help avoid a combinatorial explosion of possible program behaviors.
However, I lack the clarity of thought this late at night to make it
formal.

I'm a little out of context here, so you may perfectly well understand
this... but I suspect any rational objections you get to such a
statement come from the concern that the results of saying that a
specific function (as opposed to all functions) is mutation-only are
considerably weaker in the order analysis above than what you'd get for
a function that neither depends upon nor modifies global state.