Chris Rathman wrote: > David Hopwood wrote: >> In some other languages with dataflow variables, they have to be declared. >> For example in E (www.erights.org), "def x" declares a dataflow variable, >> while "var x" declares a mutable variable. The latter is equivalent to a >> variable associated with a first-class mutable "slot" or cell; E's kernel >> language is similar to Oz in that respect. >> >> This allows use of "var" variables that are not guaranteed initialized >> to be a compile-time error, while not making it any more difficult to use >> dataflow variables. > > Not being familiar with E, I'm guessing that it has the concept of > Futures, but not the full ability of dataflow variables.
E is not a logic language, so it does not use pass-by-unification as Oz does, and variable binding is not the same thing as unification. However, pattern matching in E works in a similar way to unification (I think it may be slightly less general in some respects). In addition, variable slots are first-class in E, so you can program variables of different kinds within the language. Dataflow variables (more precisely "promises"; see below) and mutable variables are slot types provided by the base language. > Hopefully not to be too pedantic, but futures capture part of, but not > all of the essence of dataflow variables. Specifically, futures does not > encompass the unification of Oz's dataflow variables. I think you're using a slightly nonstandard terminology here. The difference between futures and dataflow variables is not that the latter are bound by unification; it is that futures are associated with a thread. (I am counting active objects as threads here.) The general concept is a "delayed reference", which may be either unbound or bound to a value, and can be bound at most once. Sometimes delayed references can also be "broken", which is an alternative approach to throwing an execption on binding failure. The following variants of delayed references have been supported by various languages (this is not a complete list of variants that could be supported): - "futures" (e.g. in Alice ML or MultiLisp) are delayed references associated with a thread. This thread is typically created with the future, and is the only thread (by convention or enforcement) that binds the future's value. See CTM page 336 for a simulation of futures in Oz. - "lazy futures" are futures that do not start computation of their value until the value is needed. Operations that wait on the future's value cause it to become needed. - "dataflow variables" are delayed references that are not necessarily associated with a specific thread; any code with access to the variable can bind its value. - "concurrent logic variables" are dataflow variables that are bound by unification. - "concurrent constraint variables" are a generalisation of concurrent logic variables that can refer to a range of values, i.e. a basic constraint. The restriction on being bound once is relaxed to a restriction that the range of values can only be narrowed. (This need not be a primitive concept; for example a constraint variable may be implemented as a logic variable referring to an object that represents the constraint. The object is mutable, but enforces the narrowing restriction.) - "promises" are dataflow variables that support promise pipelining (http://c2.com/cgi/wiki?PromisePipelining). Notice that support for promise pipelining, binding by unification, and laziness do not conflict. In a committed-choice CCP language, concurrent constraint/logic variables can be bound to different values in different parts of a search tree. Mostly orthogonal to the above distinctions, waiting on a delayed reference can be either explicit (as in E's "when-catch" construct) or implicit (as in Oz). > Oz allows you to get > concurrency of futures and unification which manipulates futures without > having to write a different set of code depending on whether you want > sequential, concurrent, or logic based functions. Although the question > of blocking may be a stumbling block to understanding Oz, unification > implicit within Oz can also be mind altering. After all, a list > statement such as: > > X = Y|Z > > is going to blow the imperative mindset when one realizes that X may or > may not be assigned a value here. > - If X, Y and Z are known, no values will be assigned at all, but a > unification error may occur if the statement does not hold true for > the values of X, Y and Z. > - If Y and Z are known, and X is not, then X will be assigned the value > Y|Z. > - If X and Z are known, then Y will be assigned a value > - If X is known but neither Y or Z is known, then a constraint is placed > in the store which will be used for verification when code later tries > to do an assignment. > - If X, Y, and Z are unknown, then the constraint is simply stored off > for future processing. This example is equivalent to the pattern match "X ~= [Y]+Z" in E (see <http://www.erights.org/elang/kernel/MatchBindExpr.html>). In E it is also possible to write "X := [Y]+Z", which requires X to be a mutable variable, or "bind X := [Y]+Z", which requires X to be an unbound promise. I'd like to clarify something about the last two cases in your example, though. The effect in these cases is just to bind the variable X to the cons cell Y|Z, which succeeds immediately. In fact unification in Oz and pattern matching in E always succeed or fail promptly (in time proportional to the sizes of the arguments, roughly speaking); they don't create active propagators (unlike, say, "I >: 42" in Oz). E supports cons cells (and other structures) that refer to dataflow variables, but has no language support for propagators. It is not clear that propagators need to be supported in a base language, though; they can be provided as a library. Oz has some syntactic sugar for arithmetic FD constraints, but that could be simulated by macros or operator overloading. Personally, I think it is preferable to separate pattern matching or unification from assignment, and I don't agree that having to write different code for logic vs non-logic semantics is a significant obstacle. In practice, you still have to write different code in Oz for even slightly more complicated examples, such as the deterministic vs don't-know- nondeterministic versions of Append that Russ Abbott pointed out. Having to write different code for sequential vs concurrent semantics would be an obstacle, but no language that supports delayed references requires that, AFAIK. In any case, the point I was trying to make about having distinct declarations for delayed references vs mutable variables, is independent of whether delayed references are implicitly bound by unification. It is quite possible for a language to have delayed references that are bound by unification but have to be declared differently from other variables. In Oz, the syntax that is used to declare the equivalent of a mutable variable (e.g. "local X = {NewCell 0} in ...") forces some value to be specified as the initial cell contents, even when it would be more natural to initialize the contents later. This hides errors that in Java, and potentially in a language that forces dataflow and mutable variables to be declared using different syntax, would be diagnosed at compile time. > There's other patterns that are possible, but these are off the top of > my head. IIRC, CTM covers all the bases in one of the chapters. > Anyhow, futures can be used to get a lot of the effect, but there is a > bit of manual processing that has to go on to get unification to work. > The advantage of Oz is that a function can be written in such a way as > to be automatically concurrent and logic enable. You don't have to have > one function written without futures for non-concurrent processing and > one written with futures to get concurrency (dataflow processing makes > the code equivalent). "Automatic concurrency" and "automatic logic semantics" are different issues. One of the unusual aspects of Oz related to its "automatic logic semantics" is that it passes parameters by unification, which has some disadvantages. But this post is already too long, so I'll discuss that separately. -- David Hopwood <[EMAIL PROTECTED]> _________________________________________________________________________________ mozart-users mailing list [email protected] http://www.mozart-oz.org/mailman/listinfo/mozart-users
