Let me begin with a short statement on what we (I'm not alone, here, at my company)
think makes a SW product (especially a programming language) attractive: we might
call it "quality of service". One of the more important aspects of this concept
is the degree of support the programming environment provides for programmers,
especially when we consider that programmers are human, of various levels
of skill and (temporarily) subject to anything from heat to migraine. Getting good
diagnostics for as many errors as possible is one way of meeting this expectancy,
knowing that the earlier one detects an error the cheaper it is. Finally, we have also
frequently observed that implementors of some programming environment
rarely are confronted with its real world deployment; moreover, there's
also the issue that certain application areas are subject to requirements that
cherish a very high level of reliability (but not based on human factors). The last
sentence should not be understood as a criticism for members on any
particular team - it's merely saying that nobody knows it all.
The problem that Mark addresses in the blog is actually very simple.
Up to now, we simply have the binding of a variable to some fact or field,
which is written as Identfier :
and indicates the introduction of a new identifier within the current scope.
The DRL parser is capable of detecting the reference of an undeclared
identifier, and the DRL parser will duly notify you if you try to bind an
already bound identifier. A bound identifier can be used freely, LHS and
RHS, but always in an expression.
Backward Chaining (BC) introduces the need for unification, which, of course,
is an algorithm and not (primarily) an issue of syntax. We need a way of
associating an identifier with any argument of the (new) query invocation
or a field of a a pattern, both in the legacy ("named") and in the newly
introduced "positional" form.
Sticking to "Identfier :"
throughout means that there is no way of detecting
undeclared or duplicate usage.
Therefore, we propose -- for the "named" form to use
- Identfier : fieldname for binding / unifying an identifier for the first time, and
- Identfier = fieldname for all successive unification references
(Notice that no semantics regarding the in or out usage is implied.) For the
"positional" form, we propose to use
- Identfier : for binding / unifying an identifier for the first occurrence, and
- just Identfier for all following occurrences,
- and (optionally, but probably useful) just a colon : for the "anonymous" variable,
Traditional binding remains as it is; using "bound" variables in expressions is not
affected; all checks made in 5.1. can be continued.
The additional colon for positional declarative unification should not be a hardship,
especially when we consider the nice analogy to the anonymous variable being
written with an "empty" name.
For Drools programmers, the only "price" to pay is the "=" whenever they use an already
bound or unified variable
. Well, safety belts have to be put on...
A last remark: Notations using a minimum of symbols and syntactic variants are
indeed more pleasing to the eye, especially when presented in small examples. The
real test, however, is whether it can stand up to being used in more demanding situations.