Release notes - 7.4.0

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) JPLException Term JPLException JPLException JPLException JPLException
args() Term[] {} Term[] {…} Term[] {} Term[] {} JPLException Term[] {}
arity() 0 0+ 0 0 JPLException 0
atomType() “text” etc. JPLException JPLException JPLException JPLException “jref”
bigValue() JPLException JPLException JPLException BigInteger or null JPLException JPLException
doubleValue() JPLException JPLException double double JPLException JPLException
equals() boolean boolean boolean boolean xxbooleanxx boolean
floatValue() JPLException JPLException float float JPLException JPLException
hasFunctor(double, int) false false boolean false JPLException false
hasFunctor(String, int) boolean boolean false false JPLException false
hasFunctor(long, int) boolean boolean false false JPLException false
isAtom() true false false false false false
isBig() JPLException JPLException JPLException boolean JPLException JPLException
isBigInteger() false false false boolean false false
isCompound() false true false false false false
isFloat() false false true false false false
isInteger() false false false true false false
isJFalse() false boolean false false false false
isJNull() false boolean false false false false
isJRef() false false false false false true
isJTrue() false boolean false false false false
isJVoid() false boolean false false false false
isListNil() boolean false false false false false
isListPair() false boolean false false false false
isVariable() false false false false true false
longValue() JPLException JPLException long long JPLException JPLException
name() String String JPLException JPLException String JPLException
object() JPLException JPLException JPLException JPLException JPLException Object
toString() String String String String String String
type() 2 6 4 3 1 102
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.

menu
an API between SWI-Prolog and the Java Virtual Machine - hosted on GitHub