Release notes

JPL 7.4 was developed for inclusion in the stable SWI Prolog release series 7.4.x (and is included in development releases 7.5.x).

JPL 7.4 introduces one important change to JPL's public Prolog API: the use of blobs as opaque handles for references (jrefs) to objects within the Java Virtual Machine (JVM).

JRefs are now blobs

Prior to JPL 7.4.0, Prolog-side references to JVM objects were represented as compound terms e.g.

@('J#00000000000443566616')

where the atom inside the @/1 structure encodes the address of the object within the JVM. JPL exploits SWI Prolog's atom garbage collection (and its associated hooks) to effectively extend the JVM's garbage collection (GC) to treat jrefs as countable object references.

In JPL 7.4.0 we achieve the same GC cooperation using SWI Prolog's built-in support for opaque handles, as is well established for representing (for example) streams; hence a JPL 7.4.x jref is e.g.

<jref>(0x2193410)

This change will affect pre-7.4 JPL applications only if they somehow relied on the structure of jrefs, e.g. by detecting them by unification with @(_).

Note that, as with stream handles, there is no valid source text representation of a new-style jref; the following source text (or top-level input) is not only meaningless, but is a syntax error:

X = <jref>(0x2193410).

If you wish to reuse jrefs in SWI Prolog's interactive top-level interpreter, e.g.

1 ?- jpl_new('java.util.Date', [], D).
D = @('J#00000000000443566616').

2 ?- jpl_call(@('J#00000000000443566616'), toString, [], S).
S = 'Thu Jan 19 19:56:13 GMT 2017'.

then you should exploit Reuse of top-level bindings, which is also more accurate and efficient than rekeying or pasting the jref's output representation:

1 ?- jpl_new('java.util.Date', [], D).
D = <jref>(0x2193410)

2 ?- jpl_call($D, toString, [], S).
S = 'Thu Jan 19 19:56:13 GMT 2017'.

Term method orthogonality

summary: all Term subclasses support all methods, reducing need for coercions

For coding convenience, the major methods of Term's concrete subclasses (Atom, Compound, Integer, Float, Variable and JRef) are supported in JPL7 by all these classes; this reduces the need for coercions.

method Atom Compound Float Integer Variable JRef
arg(int)JPLExceptionTermJPLExceptionJPLExceptionJPLExceptionJPLException
args()Term[] {}Term[] {...}Term[] {}Term[] {}JPLExceptionTerm[] {}
arity()00+00JPLException0
atomType()"text" etc.JPLExceptionJPLExceptionJPLExceptionJPLException"jref"
bigValue()JPLExceptionJPLExceptionJPLExceptionBigInteger or nullJPLExceptionJPLException
doubleValue()JPLExceptionJPLExceptiondoubledoubleJPLExceptionJPLException
equals()booleanbooleanbooleanbooleanxxbooleanxxboolean
floatValue()JPLExceptionJPLExceptionfloatfloatJPLExceptionJPLException
hasFunctor(double, int)falsefalsebooleanfalseJPLExceptionfalse
hasFunctor(String, int)booleanbooleanfalsefalseJPLExceptionfalse
hasFunctor(long, int)booleanbooleanfalsefalseJPLExceptionfalse
isAtom()truefalsefalsefalsefalsefalse
isBig()JPLExceptionJPLExceptionJPLExceptionbooleanJPLExceptionJPLException
isBigInteger()falsefalsefalsebooleanfalsefalse
isCompound()falsetruefalsefalsefalsefalse
isFloat()falsefalsetruefalsefalsefalse
isInteger()falsefalsefalsetruefalsefalse
isJFalse()falsebooleanfalsefalsefalsefalse
isJNull()falsebooleanfalsefalsefalsefalse
isJRef()falsefalsefalsefalsefalsetrue
isJTrue()falsebooleanfalsefalsefalsefalse
isJVoid()falsebooleanfalsefalsefalsefalse
isListNil()booleanfalsefalsefalsefalsefalse
isListPair()falsebooleanfalsefalsefalsefalse
isVariable()falsefalsefalsefalsetruefalse
longValue()JPLExceptionJPLExceptionlonglongJPLExceptionJPLException
name()StringStringJPLExceptionJPLExceptionStringJPLException
object()JPLExceptionJPLExceptionJPLExceptionJPLExceptionJPLExceptionObject
toString()StringStringStringStringStringString
type()26431102
typeName()"Atom""Compound""Float""Integer""Variable""JRef"

The behaviours of arg(int) and args() are based on the behaviours of the corresponding SWI Prolog 7.x arg/3 and =../2 built-ins respectively.

The behaviours of the various isXXX() methods are based on SWI Prolog 7.x ==/2.

The behaviours of the various hasFunctor(xxx,int) methods are based on SWI Prolog 7.x functor/3.