21. Release Notes
Jess 7.1 will introduce many new features on top of the foundation laid in Jess 7.0. This is an early alpha release, so there isn't much that's new yet -- or at least, not much new that's visible. Besides a few bug fixes, the new features are discussed in the next section.
21.1. New features 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 The jess.ValueFactory class provides a pooling factory for Value objects, resulting in generally lower memory consumption if you parse a lot of data.
break The break function lets you terminate loops early as well as return from the actions of a rule without popping the focus stack.
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 definining 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.
21.3. 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-nonvalue-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.