- JavaDoc

# Jep Java

- Introduction
- Basic Usage
- Variables
- Data types
- Operators
- Functions
- Custom Functions
- BigDecimal
- Modules
- Printing
- FAQ
- Migration
- Version History

# Advanced Features

- Manipulating Expressions
- Components
- Configurable Parser
- Serialization
- Threads
- Localization
- Grammar
- Other advanced features
- Use of Design Patterns in Jep

# Jep 4 Releases

Jep 4 Releases | Jep 3 Releases | Jep 2 Releases | Jep 1 Releases

Contents:

- Versions 4.1
- Versions 4.0

## Version 4.1

### Build and testing

- Source and target Java version updated to Java 21.
- JUnit test framework upgraded from JUnit 4 to JUnit 6 (Jupiter).
- JavaCC parser now built using JavaCC version 7.0
- Partial support for Maven build system.

### Bug Fixes

- Fixed bug with `round(100000,-5) -> 99999.99999999999` in Round and RInt
- The `parent` was not always set when building node trees. `SimpleNode.jjtAddChild(Node, int)` modified to ensure this.

### Breaking changes

- Removing Observable. Since Java 9 the `java.util.Observable` has been deprecated. Code that relies on this feature has been removed, affecting the `Variable` and `VariableTable` classes. The `com.singularsys.jep.misc.VariableTableObserver` class has also been removed. The publishingvariable package serves as a replacement, see below
- The `Jep.getAdditionalComponent(Class<T> cl)` method will now throw an exceptions if two matching components are found. This is safer behaviour, but may break existing code that adds the same component twice. Outdated components can be removed with `Jep.getAdditionalComponents().remove(JepComponent comp)`.
- The `FunctionTable.addFunction(String name, PostfixMathCommandI pfmc)` will throw a `JepException` if the function is a implements `CallbackEvaluationI` and extends one of `Unary`, `Binary`, `Nary`, `NaryBinary` or `Nullary` function, as the types are not compatible.
- Console's and other example applications are no longer a Java applets.

### Spelling corrections

Typos have been fixed in a number of classes, field and method names. These changes will break existing code.

- `com.singularsys.jep.walkers`
  - Old: `PostfixTreeWalker.supressExaminingChildren(Node)`
  - New: `PostfixTreeWalker.suppressExaminingChildren(Node)`
  - Old: `TreeAnalyzer.VariableComparitor`
  - New: `TreeAnalyzer.VariableComparator` Not visible outside package
- `com.singularsys.jep.configurableparser.matchers`
  - Old: `IdentifierTokenMatcher.basicIndetifierMatcher()` this was deprecated in previous release and is now deleted
  - Old: `IdentifierTokenMatcher.basicIdentifierMatcher()`
  - New: `IdentifierTokenMatcher.dottedIndetifierMatcher()` this was deprecated in previous release and is now deleted
  - Old: `IdentifierTokenMatcher.dottedIdentifierMatcher()`
- `com.singularsys.jep - messages.properties`
  - Old: `standard.Complex.CannotModififyAnImmutableComplex`
  - New: `standard.Complex.CannotModifyAnImmutableComplex`
  - Old: `Operator.Commuative`
  - New: `Operator.Commutative`
  - Old: `walkers.PostfixTreeWalker.ExpectedSentinalOnStack`
  - New: `walkers.PostfixTreeWalker.ExpectedSentinelOnStack`

## PublishingVariable

The new com.singularsys.jep.misc.publishingvariable package uses the java.util.concurrent.Flow system of Publishers and Subscribers to provide a system to monitor changes to variables using the Observer pattern, and replaces the removed `VariableTableObserver` class.

It provides:

- `PublishingVariable` a variable which publishes changes to its value.
- `PublishingVariableFactory` a factory for creating `PublishingVariable`s.
- `PublishingVariableTable` a variable table which publishes changes such as adding variables and changes to any of the variables in table.
- `VariableTableAction` an action representing a change to a variable or table, which is sent by the publisher to subscribers.
- `VariableTableSubscriber` a base class for implementing a subscriber.
- `VariableTableUpdater` a subscriber which updates a variable table when the changes to the variables are reported.

## Overloaded functions

The new com.singularsys.jep.misc.overloadedfunctions package package allows functions to be overloaded.

- `OverloadedUnaryFunction`, `OverloadedBinaryFunction`, `OverloadedNaryFunction` each allow one of two functions to be selected during evaluation based on a predicate using the values of arguments.
- `AlternateFunctions` one of a set functions can be selected based on the number of arguments.
- `OverloadedFunctionByStructure` one of two functions can be selected based on a predicate using the structure of the Node tree.
- `AlternateFunctionGrammerMatcher` allows the parser to select a function at parse time from an `AlternateFunctions` or `OverloadedFunctionByStructure`.
- `OverloadedOperator` represents a pair of operators with different pfmc's that are selected based on a predicate on the structure of a node.
- `OverloadResolver` used to resolve operators and pfmc's after parsing, but before evaluation.

## Dictionaries

The new com.singularsys.jep.misc.dictionary package provides a grammar matcher supporting a JSON like syntax for dictionaries `map = {'x':2, 'y':3} }` and functions like `put(map,'x', 5)`, `get(map,'x')`, and `keys(map)`, for operation on on them.

## Parallel Parsing

The new com.singularsys.jep.misc.parallelparsing package has classes to allow equations to be parsed in parallel.

- `ConcurrentVariableTable` is backed by a ConcurrentHashMap and with atomic methods for adding Variables.
- `ParallelConfigurableParser` has a `parse(Reader)` method that is safe to use in multiple threads.
- `MultipleEquationParser` allows each thread to parse multiple expressions given in a single string, and the
- `MultipleEquationParsingJep` is a Jep class providing compatibility of some methods when using the ParallelConfigurableParser.

Additionally the `ConfigurableParser` class has two new constructors `ConfigurableParser(ConfigurableParser cp)` and `ConfigurableParser(Jep jep, ConfigurableParser cp)` these both reuse an existing parsers grammar and token matchers, allowing parsers that can be safely used in multiple threads to be efficiently created.

## Other changes

### Functions:

- New static factory methods to create a `NullaryFunction`, `UnaryFunction` `BinaryFunction` `NaryBinaryFunction` with a java.util.function lambda expression.

      jep.addFunction("sum",
          BinaryFunction.instanceOf((x,y) ->
               ((Number) x).doubleValue() + ((Number) y).doubleValue());
      jep.addFunction("cubrt",
          UnaryFunction.instanceOf(Double.class, Math::cbrt));

- Names for functions in `FunctionTable` and `FunctionSet` and descendents are now specified in properties files. Both now allow a function to be skipped if its name in the properties file starts with a `!`.
- A new `PostfixMathCommandI.getDescription()` method added to provide a description of the function for use in documentation. By default descriptions are found in the properties file with key `class-name.description`.
- The bigdecimal package now supports fixed-point arithmetic with a specified number of decimal places and operations on vectors. New functions `BigDecSum` and `BigDecVSum`.
- New `com.singularsys.jep.functions.RoundBD` PFMC that resolves tricky rounding cases like `round(265.335,2)`. Here a simple algorithm like multiplying by 100 and rounding fails due to inexact representation in java. The `RoundBD` function converts numbers to BigDecimals with a given scale which gives behaves better.
- New `com.singularsys.jep.misc.functions.AssignableList` PFMC that extends the `List` function and allows list of variables to be used on the left hand side of an assignment. `[x,y] = [3,4]`.
- `PostfixMathCommand.toString()` returns either the name of the function if set or the class name.
- `PostfixMathCommand.asDouble(0, arg)` work with Complex numbers when the imaginary part is zero, and throw an exception otherwise.
- `PostfixMathCommand.asType(String.class, 0, arg)` a new protected method to convert an argument to a given type.
- New interface `ZeroLengthBehaviourI` that specifies methods for setting the behaviour of functions when then encounter zero-length inputs. Has a inner enum `ZeroLengthErrorBehaviour` specifying three types EXCEPTION, NAN, VALUE.
- `ArrayFunctionBase`, now implements `ZeroLengthBehaviourI` so can now have a specified value that is returned for zero-length arrays, with corresponding constructor and getters/setters. `VSum` now respects the ZeroLengthErrorBehaviour flag, and allows custom values to be returned for zero-length arrays.
- The type of `MinMax` now be specified with an `MinMaxType` enum for a more descriptive constructor.
- `Abs` now accepts `Number` arguments, using their `doubleValue()`.
- `Comparative` now compares `List<Object>` using `eq(l,r)` to compare elements. So vectors with positive and negative zero will be considered equal.
- `Add`, `Subtract`, `Multiply`, `Divide`, `UMinus`, `Ele`, `Dot`, `Cross`, relax the type for vector arguments accepting `List<Object>` rather than `Vector<Number>`.
- New `ExpandingEle` versions of the `Ele` function whose `set` expands and modifies the `Vector` value of the variable. This can be useful for creating large lists by repeatedly adding elements.
- New `Count` function that counts the number of elements in a list
- Remove `final` modifier from `NaryBinaryFunction.eval(Object[])` and `NaryBinaryFunction.run(Stack<>)`.
- `Dot` and `Cross` have new constructors for custom implementations of Add, Subtract and Multiply.

### Main `Jep` class

- The `Jep` method `<T> T getAdditionalComponent(Class<T>)` method will now throw an exception if two matching components are found. It is now a template method so the result can be used directly without casting.
- Add a `<T> T getAdditionalComponentExact(Class<T> cl)` which checks for exact matches of components rather than instances of subclasses.
- `Jep.parse(String)` now throws a ParseException on a null string
- A new `boolean setVariableValue(String name,Object value)` method to set the value of an already existing variable.
- Add a convenience method `OperatorTable2 getOperatorTable2()` that casts the return value.
- `continueParsing()` sets the last root node on successful parses.

### Parsers and Operators

- JavaCC parser now built using JavaCC 7.0.13.
- `ConfigurableParser` has a new copy-constructor.
- `ConfigurableParser` has new methods `replaceGrammarMatcher`, `replaceTokenMatcher` to make it easier to modify an existing parser.
- Support for a range operator `[1..5]` moved from the extensions package to the core, with a new `RangeOperator`, `Range` function, a matcher `ListOrRangeGrammarMatcher`, and `ConfigurableParserWithRange` which has the new grammar matcher.
- The `ExtendedOperatorSet` now allow Unicode superscripts as suffix power operators like `x²` and `x³`. New `JccArrayAccessGrammarMatcher` that produces node trees matching the produced by the `JccParser`.
- `EmptyOperatorTable` has a new `getKeys(Operator)` method and deprecates `getKey(Operator)`. `removeOperator(op)` now removes all associated keys and `replaceOperator(Operator oldOp, Operator op)` throws and exception if multiple keys are found. It also deprecates `getOperatorsByName(name)` and adds `getAllOperatorsByName(name)` `getOperatorByName(name)`.
- New `ConfigurableParser.getToken(String)` method to search for matching OperatorTokens and SymbolTokens.
- `ShuntingYard` modified to allow both the ternary operator syntax `x>y ? x : y` and the new dictionary syntax `{'x' : 3}`.

### Component architecture

- Add a constructors to `StandardComponents`, `LightWeightComponentSet` and `MediumWeightComponentSet` to allow preferred components to be specified. To achieve this a protected method `ComponentSet.findOrElse(JepComponent[], Class<T>, Supplier<T>)` looks for an instance of a class in the components, if not found the supplier is used.
- New `com.singularsys.jep.walkers.LightWeightImportationVisitor` needed to `MacroFunctions` work with Overloaded functions. `MacroFunctions` modified to work with the `LightWeightImportationVisitor`
- New `OneShotComponent` base class for components that should only be initilised once. The `FunctionSet` and `StringFunctionSet` classes now extend this class, prevents conflicts with manually adding functions.
- A default method `eval(NodeFactory nf, String name, PostfixMathCommandI pfmc, Node... children)` added to the `Evaluator` interface to allow a NodeFactory to be used to create nodes.

### Visitors

Most visitors have been reworked to implement the `com.singularsys.jep.GenericVisitor` interface, which provides better type safety and more specific method signatures.

- New `GenericVisitor<R,D,E>` that offers better type safety with the return type, context data type and exception type all specified by type parameters.
- New base classes `GenericDoNothingVisitor<D>` and `GenericDeepCopyVisitor<D>` for visitors that return a new Node tree.
- New `TestingVisitor` that uses a predicate to test every node in a tree.
- New `LightWeightImportationVisitor` using the LightWeightInstance of pfmc if needed.
- Visitors reworked to use switch expressions and pattern-matching.
- The `ImportationVisitor.deepCopy(Node)` method is now deprecated, the more descriptive method `importEqn(Node n)` should be used instead.

### Variables and VariableTables

- Add a new method `Variable.copyPropertiesFrom(Variable)` that copies properties like its constant status, valid value status, and hooks from an existing variable.
- The `VariableTable.copyVariablesFrom(VariableTable vt)` and `VariableTable.copyConstantsFrom(VariableTable vt)` modified to use this method and use the `addVariable()` and `addConstant()` methods, ensuring the correct type of variable is always created.
- Better behaviour of `Variable.toString()` using getter methods rather than accessing fields directly, so that subclasses can modify the behaviour.
- New `DecoratingVariableTable` allowing a VariableTable to be decorated with additional behaviour. This serves as the base class for the `CaseInsensitiveVariableTable` and `PublishingVariableTable` allowing both to be used together.
- `CaseInsensitiveVariableTable` now extends `DecoratingVariableTable`.
- `CaseInsensitiveVariableTable` now overloads `addConstant()` and `addVariable()` and `remove()`.

### Console applications

- No longer a Java applets. This may break some code.
- Add a `setarrayoffset` command to set whether zero or one-based array indexing is used.
- Add a `clearvariables` command which removes all variables and constants
- Use `$1` and `$$` for values from previous results.
- Descriptions of functions are printed in the `functions` command
- The call tree can be monitored to record the number of times each function operator or variables called and the time spent. This can be switched on using `setMonitor` and a summary of numbers of calls printed using `showCalls` and the call tree using `showTree`.
- Add several new overridable methods method to the `Console` class: `getHistory()`, `printFunctionEntry(name,pfmc)`, `setIndexShift(offset)`, `clearVars()`, `setMonitor()`, `setEvaluator(ev)`, `showCalls()`, `showTree()`, `finaliseCommand(name, node, res)`.
- All consoles now support multi-line strings with `\\` at the end of a line.
- The `BigDecimalConsole` supports fixed point arithmetic.

### General

- New method `Node.getChildren()` returns an array of the children of a node. Implemented in `SimpleNode`.
- `Operator.toFullString()` reports the Not-in-parser flag. to make it easier to modify an existing parser.
- Adds a new `com.singularsys.jep.misc.StrictDoubleNumberFactory` class that is a stricter version when all methods return Double.
- Add `PrintVisitor.visit(Node)` method than can be called from PrintRulesI classes.
- `PrintVisitor` has additional methods `getSpecialRule(Operator)`, `getSpecialFunRule(String)` and `getSpecialVarName` to interrogate existing setup.
- `NullPrintVisitor` has do-nothing implementations of some methods to prevent exceptions if called.
- `JepMessages` now allows additional resource bundles to be added
- New `MonitoringEvaluator` that counts the number of times each function, operator and variable and constant is used during evaluation.
- New html documents describing printing options
- New html documents describing usage of design patterns in Jep.
- Most console output of JUnit tests can be turned off by setting the `DO_NOT_PRINT_TESTS` environment variable to true.
- Tags `@Tag("slow_tests")` and `@Tag("known-failure")` added to JUnit tests, allowing slow tests and known failures to be excluded.

## Version 4.0

### Add support for Java Modules

A modularized version of Jep for use with Java 11 is available in the `modules` directory. The code is written to be compatible with both long term support versions Java SE 8 and Java SE 11.

### Handling of non-thread safe functions

Most functions can work fine in multiple threads, there are some which need special treatment. These functions can be indicated by implementing `JepComponent` which provides a `getLightWeightInstance()` to return a thread-safe copy of the function.

When using the `FunctionTable` and `OperatorTable` in multiple threads their `getLightWeightInstance()` methods will just return `this` which is more memory efficient in the default case. This is the behaviour in Jep 3.4 and earlier.

Starting in version 4.0, both `FunctionTable` and `OperatorTableI` have `shallowCopy()` methods. This will create new instance of the table and copies all functions operators into the new table. If the function implements `JepComponent` then its `getLightWeightInstance()` is called to return a thread-safe version.

There is also a `MediumWeightComponentSet` class which can be used to create a Jep instance which insures thread-safe versions of functions. To use

    Jep jep = new Jep();
    Jep copy = new Jep(new MediumWeightComponentSet(jep));

and the copy instance can be safely used in new thread.

To implement this functionality FunctionTable, and EmptyOperatorTable have protected `threadSafeMapCopy()` methods which returns a copy of the internal map respecting JepComponents. They also have protected `FunctionTable(Map<,>)`, `EmptyOperatorTable(Map<,>)` constructors. This allows subclasses it easily implements this behaviour

    class MyFunctionTable extends FunctionTable {
        ...
        protected MyFunctionTable(Map<String, PostfixMathCommandI> tbl) {
    		super(tbl);
    	}

    	public FunctionTable shallowCopy() {
        	Map<String,PostfixMathCommandI> newMap = this.threadSafeMapCopy();
            FunctionTable ft = new MyFunctionTable(newMap);
            return ft;
        }

All subclasses also implement these constructors.

The Jep 3.5 release had a broken implementation of `getLightWeightInstance()` which would always return an empty table.

### Evaluation

A new `UncheckedEvaluator` evaluator which does no checking of intermediate values during evaluation. Produces a 10-20% speed increase.

Slight change in the logic of the `FastEvaluator`. Test for functions which implement `CallbackEvaluationI` happens after tests for `UnaryFunction` etc.

### Support for Lambda expressions

The `UnaryFunction`, `BinaryFunction` and `NaryBinaryFunction` have static factory methods which allow creation using lambda functions. For example

    // Function using explicit class
    UnaryFunction recip = UnaryFunction.instanceOf(
             x -> 1.0 / ((Number) x).doubleValue());
    // Function where arguments are of an explicit type
    UnaryFunction neg = UnaryFunction.instanceOf(Integer.class, x -> -x );
    // Function using a method reference
    UnaryFunction cubrt = UnaryFunction.instanceOf(Double.class,Math::cbrt);
    // Binary function
    BinaryFunction diff =  BinaryFunction.instanceOf(Number.class,
            (x,y) -> x.doubleValue() -  y.doubleValue());
    // NaryBinaryFunction
    NaryBinaryFunction sum =  NaryBinaryFunction.instanceOf(
            (x,y) -> ((Number) x).doubleValue() + ((Number) y).doubleValue());

### Complex

- New `ImmutableComplex` class who's values cannot be changed, and the results of all operations yield immutable results.
- The constants `Complex.ZERO`, `Complex.ONE`, `Complex.I` are now immutable, but for compatibility results of operations using these constants can be changed. These constants use the `Complex.NonPropagatingImmutableComplex` inner class.
- More efficient power methods. The main `power(Complex w)` methods checks to see if the argument is an integer, if so the `power(int n)` method is used. This in turn calls either `fastPower(int n)`, or `powerI(int n)`. The first of these is faster but may be less accurate for large powers. A new `powerD(double d)` is also introduced which uses the general double algorithm `[r:th] -> [r^d:d th]`.
- Better unit testing of the class.
- A new `SpeedTestComplex` diagnostic class.
- Finer control of format of Complex numbers using new message properties. Property `standard.Complex.ToStringImaginaryWithI` removed and properties `standard.Complex.ToStringNoBracketsRealWithI={0}` `standard.Complex.ToStringNoBracketsNegRealWithI=-{0}` `standard.Complex.ToStringNoBracketsImaginaryWithI={1} i` `standard.Complex.ToStringNoBracketsImaginaryWithNegI={1} i` `standard.Complex.ToStringBracketsRealWithI={0}` `standard.Complex.ToStringBracketsNegRealWithI=-{0}` `standard.Complex.ToStringBracketsImaginaryWithI={1} i` `standard.Complex.ToStringBracketsImaginaryWithNegI={1} i` added.

### Bug Fixes

- Fixed bug in `MacroFunction` which could give incorrect results on recursive functions.
- The `Complex.reciprocal()` gave incorrect results when im!=0.
- In `PostfixTreeWalker` the `visit()` methods are now called with the correct number of children in cases when `supressExaminingChildren(Node)` returns true.

### Other changes

Parsing

- Add new `BracketedSequenceGrammarMatcher` `FunctionSequenceGrammarMatcher` which parses lists and sequences, but the sequences separator `,` is treated as a normal operator, and sequences passed using the ShuntingYard.
- Change order of SymbolToken and OperatorTokens in the `StandardConfigurableParser` so a multi-character symbol would be recognized before a single character matching operator.
- Modify RegExp for `NumberTokenMatcher` so that `1..2` is not misinterpreted.

Functions and operators

- The `Operator` class has a new `duplicate()` method creating a new operator with an identical set of fields.
- The `EmptyOperatorTable` now has methods `addOperator(new_op,existing_op)` `insertOperator(new_op,existing_op)` `appendOperator(new_op,existing_op)` which don't require an explicit key to be specified.
- The `TernaryConditional` function now use lazy evaluation.
- The `TernaryOperator` implements `PrintRulesI`.
- New interface `NullWrappedPassThroughFunction` for functions which should not be wrapped in the `NullWrappedFunctionTable`.
- The `MacroFunction` now has a working `getLightWeightInstance()` method. It has a new constructor allowing a node tree to be specified. This allows use in threads which do not have parsers. Fields now made protected to allow subclasses. Now catches stack errors on evaluation.
- Relax condition on the `Power.power(int)` to be strictly positive, as it was too fragile.

Printing

- The `PrintVisitor` allows operators to implement `PrintRulesI`.
- The `PrintVisitor` now has public visibility for the `testLeft()`, `testMid()` and `testRight()` functions allowing them to be used in a PrintRule. allows operators to implement `PrintRulesI`.
- PrintVisitor with a number format will always use that format, even for NaN and Infinity. Use the `java.text.DecimalFormatSymbols` to set the strings used.

Variables

- `VariableFactory.copyVariable(Variable var)` now copies all information about the source variable, including constant flag, valid value flag, and hooks.
- `VariableTable.copyVariablesFrom(VariableTable vt)` and `VariableTable.copyConstantsFrom(VariableTable vt)` copies all information about the source variable, including constant flag, valid value flag, and hooks. If there already is a variable with the same name all properties are copied and pre-existing hooks deleted.

Light weight components, hooks and serialization

- The `ImportationVisitor` now ensures it gets its operators and functions from the specific Jep instance.
- `LightWeightComponentSet` makes lightweight instances of the additional components.
- `Node.HookKey` is now Serializable and information on hooks is includes in `SerializableExpression`. Some care is needed to ensure implementations of HookKey are properly deserialized, and the use of SerializableExpression between versions.
- `DeepCopyVisitor` copies information about hooks on each node.
- Add a `HookRemover` walker which removes hooks from nodes.
- Fix minor bug with `Collection<HookKey> hookKeys()` methods of `Node` and `Variable` when no keys set.

Other changes

- Add a `JepRuntimeException` for use in cases where a normal JepException cannot be thrown.
- The `JepMessages` class has new `String format(String key,Object ... args)` methods to make it easier to use a message to formats its arguments.

Examples and tests

- The `Fractal` example application reworked to use multi-thread approach.
- More extensive unit testing and some reorganization of testing packages.