Workaround for features missing in JXN
Note: Some of the following issues may contain legal but weird constructs. If you don't understand an issue right away, don't bother, most probably you will not need it.
Class definitions:
- define the class in a java source file, make your class (file) available in the classpath and call public methods of your class from jxn
⇒ best performance (see UserDefinedClasses)
- jxn script files support basic function definitions including
#if...
and #while...
control structures using jxn special commands:
see JxnScripting and JxnPortable/docs/ how to use jxn script files and how to define a JxnFunction
L-value expressions:
Java | jxn workaround *) |
arr[indexExpression] = expression | set( arr, indexExpression, expression ) |
obj.fieldName = expression **) | set( obj, "fieldName", expression ) |
*) see class
JxnUtilities
,
set
(array),
set
(field)
**) Note: often a class provides a setter method:
obj.setFieldName( expression )
Note: slider dependency is not transfered to
arr
and
obj
=> subsequent statements depending on
arr
or
obj
are not repeated,
see
SliderRepeatNopDemo.html and use
nop(depVar)
to force repetition of statements depending on
arr
or
obj
.
Numeric literals:
The following table shows possible workarounds for java numeric literals not supported by jxn:
result | java numeric literal | jxn workarround |
|
@ (char) | '\100' // octal | Short.parseShort( "100", 8 ).charValue() |
|
12 (int) | 0b1100 // binary | Integer.parseUnsignedInt( "1100", 2 ) |
-12 (int) | 0b11111111111111111111111111110100 | Integer.parseUnsignedInt( "1111…11110100", 2 ) |
12 (int) | 014 // octal | Integer.parseUnsignedInt( "14", 8 ) |
-12 (int) | 037777777764 // octal | Integer.parseUnsignedInt( "37777777764", 8 ) |
123456789 (int) | 0x075b_cd15 | JxnUtilities.parseHex( "075b_cd15" ).intValue() |
-123456789 (int) | 0xf8a4_32eb | JxnUtilities.parseHex( "f8a4_32eb" ).intValue() |
|
12 (long) | 12L | (12).longValue() |
-12 (long) | -12L | (-12).longValue() |
12 (long) | 0xcL | JxnUtilities.parseHex( "c" ).longValue() |
-12 (long) | 0xffff_ffff_ffff_fff4L | parseHex( "ffff_ffff_ffff_fff4" ).longValue() |
1234567890987654321 (long) | 1234567890987654321L | 1234567890987654321 ! parsed as long by jxn |
-1234567890987654321 (long) | -1234567890987654321L | -1234567890987654321 ! parsed as long by jxn |
1234567890987654321 (long) | 0x1122_10f4_b16c_1cb1L | parseHex( "1122_10f4_b16c_1cb1" ).longValue() |
-1234567890987654321 (long) | 0xeedd_ef0b_4e93_e34fL | parseHex( "eedd_ef0b_4e93_e34f" ).longValue() |
|
1.25 (float) | 1.25f | (1.25).floatValue() |
-1.25 (float) | -1.25f | (-1.25).floatValue() |
1025.5 (float) | 0x1.006p10f | Float.parseFloat( "0x1.006p10" ) |
-1025.5 (float) | -0x1.006p10f | Float.parseFloat( "-0x1.006p10" ) |
|
1.2345678909876543 (double) | 0x1.3c0ca42c7bd1bp0 | Double.parseDouble( "0x1.3c0ca42c7bd1bp0" ) |
-1.2345678909876543 (double) | -0x1.3c0ca42c7bd1bp0 | Double.parseDouble( "-0x1.3c0ca42c7bd1bp0" ) |
see also
hex_formatting
in
JxnUtilities
and docs/
Varargs methods calls:
Supposed a method is defined as follows:
public static int max( int... a )
{
int result = Integer.MIN_VALUE;
for( int e : a )
{
if( e > result ) result = e;
}
return result;
}
In Java the method can be called (applying the varargs feature):
max( 3, 7, 5, 1 )
In JXN the method must be called like this:
max( { 3, 7, 5, 1 } )
or
max { 3, 7, 5, 1 }
In any case the calls return the result 7.
Automatic array unroll does not support polymorphism
sqrt( { 2, 3, 5 } ) ! works
= { 1.4142135623730951, 1.7320508075688772, 2.23606797749979 } (double[3])
! but
sqrt( { t, j, 3. } ) ! is not (yet) supported
? invokeMethod: identifier sqrt( java.lang.Object[3] ) undefined,
! workaround (using class JxnLoop
):
JxnLoop.fill( $this, "$p", { t, j, 3. }, "sqrt $p;" )
= { {0.0, 0.044721359549995794, ... 1.0},
= 0.7071067811865476 + j 0.7071067811865475 = 1.0 <) 45.0°,
= 1.7320508075688772 } (java.lang.Object[3])
No memory optimization for augmented assignment
JXN handles
variable_name op= expression
as a syntactical shortcut of
variable_name = variable_name op ( expression )
and always assigns a new instance to
variable_name
rather than modifying the existing instance
variable_name
is referring to.
This avoids an obscure side effect observed in programming languages e.g. →
Python where
→
augmented assignment may (or may not) modify the existing instance referred to by
variable_name
(see docs/).
If for memory optimization reasons the creation of a new instance must be avoided, call:
variable_name.opMethod( expression )
Specification of class objects for arrays and java primitives:
Note:
ClassName.class
works in jxn as in java
specification of class objects in Java | workaround in JXN |
|
package_name.ClassName[].class | Class.forName("[Lpackage_name.ClassName;") |
ClassName[][].class | Class.forName("[[LClassName;") *) |
|
double[].class | Class.forName("[D") |
double[][].class | Class.forName("[[D") *) |
float[].class | Class.forName("[F") |
long[].class | Class.forName("[J") |
int[].class | Class.forName("[I") |
short[].class | Class.forName("[S") |
byte[].class | Class.forName("[B") |
char[].class | Class.forName("[C") |
boolean[].class | Class.forName("[Z") |
|
double.class | Double.TYPE |
: | : |
boolean.class | Boolean.TYPE |
*) For multidimensional arrays
'['
is repeated e.g.
[[[
for three dimensional arrays.