Oracles


Doctoral thesis for the degree of Doctor of Philosophy

Fudgets --

Purely Functional Processes with applications to Graphical User Interfaces

Magnus Carlsson
Thomas Hallgren

Carlsson and Hallgren's 1998 thesis on functional window gadgets is of course not new. However, I want to call attention back to it because it discusses the idea of an Oracle. I submit that the notion of a system that supplies oracles (as many as needed) from the runtime environment provides the best way to account for nondeterminism/indeterminism in a notation or a framework of reasoning that embraces Referential Transparency. I submit that Oracles should be more on the minds of those who write about designs for pure functional programming languages and systems than they seem to be today.

(Unfortunately, the term "Oracle" in this meaning is not in practice Googlable, because anything you'd turn up would be swamped by the returns about the Oracle brand database management system.)

When I say indeterminism, the kind of indeterminism I'm talking about is the kind where information comes from various sources over rough roads, and the right thing to do is act differently depending on what information happens to arrive first, affecting output. The right thing to do for the sake of the humans the computer is interacting with may also depend on the time required for various calculations. So there needs to be a way to model the fact that a routine needs to ask for a calculation that actually takes up time. A referentially transparent language can talk about what has to be calculated, but it has trouble dealing with the fact that calculations can cost something and sometimes one may finish before or after another, or before or after some system input (e. g., command from human to go get some other information, or maybe to query the status of the calculation, or change the resources devoted to it or the priority of their use, or suspend the calculation, or cancel it).

Given an oracle o from the environment, and two data sources a and b, we can have a function decide, where decide(o, a, b) returns something like (Left, a) if a is available before b, or (Right, b) if b is available first (assume Left and Right are just symbols, distinct from one another). This operation consumes the oracle o and no attempt must be made to use it again. The Referentially Transparent explanation for why this function application is able to determine whether the computation of a or b finished first is that from its magic knowledge from the gods, o knew all along which calculation was destined to finish first, hence the metaphor of an oracle as the term for this concept. Of course, an oracle can't be printed. It's just used once, at the point where the reality of the outcome is going to be determined, and of course the prediction never fails since it can't in practice be tested as a prediction.

An alternative way to model indeterminism in the framework of referential transparency is via the sets of Hughes and O'Donnell. I thank Fergus Henderson for his easy-to-understand explanation of the Hughes/O'Donnell approach. The outputs of indeterminate function applications are understood to be sets of all possible results. The implementation only outputs one of the results, however, at the exit to the system. I used to think I could articulate an argument why this approach will not satisfy so well as the oracles approach. In the Hughes/O'Donnel sets account, intermediate results are not understood to contain any decision about what result was computed (although of course in the implementation, the decision would be made and only its result stored). Since the result contains in concept all the possible results, I'm not sure there is a semantically sound way to think about storing it persistently so as to avoid having to repeat long calculations in case of a crash of the volatile memory. Maybe bye and bye I'll think of an argument again on the comparison of these approaches. Or maybe someone else will.

Does anyone propose a third answer?

It seems to me that in the design of a programming system demonstrating orthogonal persistence (transparent persistency), the consumption of an oracle may be a significant event. Or maybe not, maybe in such a design, all itermediate results are as significant as the time it took to calculate them. The real significant event is system output, because that embodies the decisions taken at all the indeterminate choice points that contributed to the output. Subsequent outputs have to honor those choices.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

In the olden days

LML had a fully fledged implementation of oracles running of a multi-processor (a Sequent Symmetry) back in ca 1989. The description in the Fudgets thesis refers to this implementation. It was fairly pleasent to work with and quite practical.

Since the constraint that an oracle can only be used once could not be statically guaranteed we instead allowed oracles to be used multiple times. Normally you would not do this, but if you did the right thing happened, i.e., an oracle makes the same choice every time you use it.
A benefit of this is that you could have a non-deterministic program, but if you happen to save the tree of oracles you could actually run it again with the same choices made.

These days everything is done with monads so other solutions are sometimes forgotten.

Re: In the olden days

Thanks, lennart, for the enlightening comment. I had never thought of the idea of allowing multiple uses of the oracle, where the implementation would just make sure that all uses reflected the same choice.

". . . you could actually run it again with the same choices made." -- Sounds like a boon for regression testing.

Your recollection of oracles as pleasent to use and practical suggests that I may be barking up the correct tree.

Also, it's good that we now have some reference to (or closer to?) where the oracle idea first came up. I remembered that Carlsson and Hallgren didn't claim to have originated it. But their paper certainly informed me about the idea.

As for monads, I don't think they're a solution to this problem. They're just a layer of notation over the pure functional model. Unless maybe the "state" carried along inside the monad is a stream of oracles, or maybe a Hughes/O'Donnel set? How do the Haskell mavens write non-deterministc programs? Do they at all?

(By the way, this thread should probably mention "commited-choice" to attract searches on that term. Henderson, my Hughes/O'Donnel explainer, says committed-choice nondeterminism is what my question really was about.)

Oracle inventor

I don't know who first came up with the idea, but both Warren Burton and I had the idea. Warren published about it first, so I never wrote anything much about it.

In Haskell of today you would do it by forking a new thread using forkIO and use, e.g., an MVar. This pushes the non-determinism into the kitchen sink, the IO monad.

Alan Turing

The concept of oracle was created by Alan Turing.
Search "oracle" in this link:
http://plato.stanford.edu/entries/turing/

Turing Oracles Different

That's an interesting reference. I'm not quite sure of all the implications of Turing's "oracle"; however, I'm quite sure it isn't the same as the oracle under discussion here ("lennart/Burton oracles"?). In the article about Turing, it says he said that no machine could do the oracle thing. But our oracles here just need to "know" which computation finshes first or which data arrive first or whether a computation finishes before an input event, that sort of thing, which the real machine does decide or determine or discern. After all, many of these programs have been written to handle events based on the order that they happen in and they run on real computers and execute correctly. It's easy to see how to write them in assembly language. The machine knows. The point here is to be able to express those programs with referential transparency.

I forgot about the original Turing "not a machine" requirement

Formal oracle machines treat the oracle as a black box that could be a machine.

[edit: wikipedia link added]

LIM

Apropos of nothing, your description of oracles reminded me of a very cute language: LIM, the Language of the Included Miracle. (That is the only currently available reference I can find; lim has been around for quite a while.)

Haskell and Indeterminism

So what are the components of the argument to and result from applying the main routine in Haskell that concern indeterminism (the temporal kind)? For that matter, what are those that concern I/O? Describe without reference to the monad. The monad is, after all, only notation.

In other words, exactly what is being buried in the kitchen sink? Dig it up for me, please. I want to sniff it.