21. Release Notes

Jess 7.1 introduces some new features on top of the foundation laid in Jess 7.0.

21.1. New features in Jess 7.1

Templates inherit declarables from parent. In particular, templates inherit backwards chaining reactivity and slot-specific behavior from their parent template (if they have one.)

Test CEs allowed in logical. You're now allowed to use test inside of the logical CE.

Alternative character sets. The batch function and the jess.Batch class's various methods can accept a charset argument, so Jess can read files written in arbitrary character sets.

Test CE folding. The test conditional element is now more efficient -- in fact, its performance is equivalent to declaring the same tests somewhere in the preceding pattern. A test pattern is no longer compiled to a real join node in the Rete network. You can now use the test CE anywhere you want to improve program readability or in generated code, without penalty.

Automatic strength reduction. Many uses of the "eq" and "neq" functions in the patterns of a rule will be automatically converted to more efficient direct matching. Although direct matching is still to be preferred because it is less verbose, generated code can use "eq" and "neq" uniformly with other functions and Jess will do this optimization when possible.

Dot notation. The "simplified" or "Java" patterns can now use a "dot notation" to reference slots in other patterns. This powerful capability greatly expands the usefulness of Java patterns and makes auto-generating Jess code much easier. Futhermore, The notation "?x.y" in procedural code will be interpreted as "slot y of the fact in x".

Name restrictions.Slot names and variable names may not contain a period ('.').

Variables not bound by Java patterns. The semantics of Java patterns, introduced in Jess 7.0, have changed slightly. These patterns no longer bind user-accessible variables to any slots they're used in. To access slot values of facts matched by Java patterns, use the fact-slot-value function or the jess.Fact.getSlotValue(java.lang.String) method.

allowed-values. Template slots can now use the allowed-values qualifier, which states which discrete values a slot can hold. Jess will verify that your code obeys this statically; optionally, it can also be verified at runtime. Using allowed-values where appropriate will take advantage of some new optimizations to be implemented in Jess 7.1.

Peering of Rete objects. jess.Rete objects can share their rule networks, resulting in reduced memory footprint and faster setup times when you're using multiple engines in a single application.

elif. The if function supports elif blocks.

ValueFactory. Jess uses a pooling factory for Value objects, resulting in generally lower memory consumption if you parse a lot of data. You can use the same factory for the Value object you create. If you modify your code to use it, you can conserve memory since ValueFactory caches some of the Values it creates. HashCodeComputer, the class that Jess uses to keep track of which objects a "value objects", is also public.

break. The break function lets you terminate loops early as well as return from the actions of a rule without popping the focus stack.

Removing constructs. The jess.Rete class now includes methods for removing modules, templates, globals, and all other constructs.

21.2. New features in Jess 7.0

Jess 7 has many new features. The manual has had a major rewrite for this version, although some new features may be underdocumented. These notes are intended to help with that.

New features in Jess 7 include, in no particular order:

Java patterns. You can use a new, simplified syntax for pattern matching that looks a lot like Java Boolean expressions. You can read about it here.

Static imports. Importing a class now causes all its static members to be defined as functions. See here for details about this new and useful feature!

Lambda expressions. You can now create unnamed functions and easily use them to implement Java interfaces. See here for details.

New default for definstance. The definstance function's default behavior is now to use PropertyChangeEvents whenever they are available. It's generally not necessary to use the "static" or "dynamic" qualifiers anymore, unless you want to force Jess not to use a PropertyChangeListener even when that facility is available. You can explicitly use a qualifier of "auto" as a synonym for the default.

Eclipse-based IDE. Charlemagne includes a rule development environment called "JessDE" based on the Eclipse open-source IDE. The toolset includes an editor, a debugger, and a host of small tools to help with rule development and deployment. You can read more about it here.

Simplified defquery syntax. A new run-query* function brings a JDBC-like interface to working memory queries. Read about it here.

The "slot-specific" declaration for templates. Deftemplate definitions can now include a "declare" section just as defrules can. There are several different properties that can be declared. One is "slot-specific". Changes to facts from slot-specific templates won't trigger rule activations unless the modified slot is actually mentioned on the LHS of the rule.

The "backchain-reactive" declaration for templates. This declaration lets you declare that a template is backward chaining reactive when you create it, rather than after the fact.

The "from-class" declaration for templates. This provides a different syntax for defining templates based on Java classes. Using "from-class", you can apply all the other template declarations to shadow fact templates.

Public member variables as slots. When you define a template using the deftemplate from-class syntax or using the Rete.defclass() method, you can tell Jess to include public member variables as slots in the template. Do this by passing "true" as the optional fourth argument to Rete.defclass(), or by including the declaration "(include-variables TRUE)" in your deftemplate. There is not yet a way to turn this feature on when using the defclass function.

The "no-loop" declaration for rules. If you use (declare (no-loop TRUE)), then nothing that a rule does while firing can cause the immediate reactivation of the same rule; i.e., if a no-loop rule matches a fact, and the rule modifies that same fact such that the fact still matches, the rule will not be put back on the agenda, avoiding an infinite loop.

Matching with regular expressions, and the regexp function. Under JDK 1.4 and up, Jess 7 has regular expressions support. You can directly match any field with a regular expression.

The -stacktrace switch. The error messages printed by the jess.Main class have always (deliberately) included a stack trace to help you find the specific part of Jess that rejected your input. Unfortunately, stack traces are frightening to many non-programmers. Furthermore, some people assume that when they see a stack trace, they're seeing a bug in Jess. Therefore, jess.Main's new default behavior is not to display a stack trace on error. To get the old behavior, you can include the -stacktrace command-line switch when you start jess.Main.

RU.LONG is now a first-class type. You can write long literals by appending an "L" to an integral value. Values of "long" type can now be used in arithmetic and logical expressions. The long function still exists but, as it's no longer needed, it is deprecated.

The "forall" conditional element. Jess now includes a "forall" conditional element. The "forall" grouping CE matches if, for every match of the first pattern inside it, all the subsequent patterns match. See here for more information.

The "accumulate" conditional element. The "accumulate" CE is lets you count facts, add up fields, store data into collections, etc, all as a part of pattern matching. See here for more information.

Subrules no longer user-visible. The "or" CE causes rules that use it to be broken into subrules, as described in the manual. However, the individual subrules will no longer be visible to the user; they're an implementation detail that should not concern most programmers.

Native XML parser. Jess 7 defines its own XML rule format, JessML, designed so that it's easy for the language to support Jess's special features. An XML Schema file describing this format is included in the distribution. We hope to eventually provide XSLT scripts to transform this language into RuleML and other standard rule languages. Several examples of the XML format are included in the examples directory which are exact machine translations of standard Jess examples. The batch function knows how to read these XML files in, and there are a number of useful public Java classes in the package jess.xml for working with this new format, including a tool to translate any Jess code into JessML.

Public API for rule creation. The XML parser is defined in its own package, and works by creating jess.Defrule objects using the Java API. This is an existence proof that such a thing is now possible. Documentation on how is forthcoming.

Better handling for objects with mutable hashCodes. Object identity in Java is a slippery thing, as experienced programmers know; the interpretation of identity and equality can be intimately tied to the class-specific implementations of the equals and hashCode methods. Jess has historically had some problems with Java objects whose hash code changes over time. These problems have been resolved in Jess 7. Objects with changing hashCodes can be safely added to working memory even in situations that have caused problems in the past. See "Java objects in working memory" for details.

Better reflection performance. Jess's performance while scripting Java objects in procedural code has improved by 20-50% in this release, especially in loops.

Better method names. The RU.EXTERNAL_ADDRESS constant, the jess.Value.externalAddressValue() method, and the external-addressp function are all deprecated in favor of the new equivalents RU.JAVA_OBJECT, jess.Value.javaObjectValue(), and java-objectp.

New overloaded add() methods. The jess.ValueVector class has a new set of overloaded add() methods that make Java code that uses Jess lists look cleaner.

CLEAR. One minor but potentially important behavioral change in this release is that the jess.Rete.clear() method doesn't modify the event mask, set of event listeners, or watch state. Although this is a break with the traditional semantics of the clear() method, it makes more sense, especially for embedded applications.

21.3. Porting from Jess 7

Jess 7 code will generally run fine in Jess 7.1, with a few small exceptions. One issue is that the period character '.' is no longer valid in variable or slot names, since the period is now used as a "dot operator" to denote membership. If this breaks existing code, you can choose to use some other character (we suggest the octothorpe '#') as a membership operator by adding the following to the beginning of your Jess code:

            ((engine) setMemberChar #)
          

21.4. Porting from Jess 6

In general, Jess 6 applications will run unchanged (either Java API code, or Jess language code,) with a few exceptions, as noted below. Nevertheless, you may want to change your application to take advantage of some of the newer features -- for example, the new run-query* method.

Restrictions on variable names. Jess 7 accepts a more limited syntax for variable names than did earlier versions of Jess. Only letters, numbers, dash, asterisk, colon, and underscore are legal characters in variable names in this release; in particular, the period (.) character is no longer allowed as part of a variable name. Hopefully this won't affect any existing code.

Newly deprecated methods. The Rete.executeCommand() method is deprecated in favor of the new eval() method.

Previously deprecated methods removed. All deprecated methods from Jess 6 have been removed from Jess 7. In particular, the "assert()" method from the Rete class has been replaced with "assertFact()".

New deprecated functions.The Jess function "multifieldp" is now deprecated; use "listp" instead. The RU.EXTERNAL_ADDRESS constant, the jess.Value.externalAddressValue() method, and the external-addressp function are all deprecated in favor of the new equivalents RU.JAVA_OBJECT, jess.Value.javaObjectValue(), and java-objectp.

USERFUNCTION_CALLED events.The data associated with a JessEvent of type USERFUNCTION_CALLED is no longer a Userfunction object; it's now a Funcall object.

Context.setVariable() behavior changed.The setVariable() method of jess.Context behaves a little differently now. In general, you won't notice a change unless you were using variables defined at the command prompt as if they were global variables. They never were, and never acted as if they were -- and they're even less so now.

Arguments to "batch".The path argument to the Jess function "batch" must be a double-quoted string; using an unquoted symbol instead will lead to undefined behavior.

Value objects. Jess now assumes that all objects (except for Collections) are value objects by default. If you're working with a class that is not a value class, it's very important that you tell Jess about it by using the set-value-class function. See "Java objects in working memory" for details.

Return types. A very few public methods that used to return concrete collection classes are now declared to return the corresponding interface; for example, Rete.getSupportingTokens() now returns List rather than ArrayList.