This is documentation for Mathematica 5, which was
based on an earlier version of the Wolfram Language.
View current documentation (Version 11.2)

Documentation / Mathematica / Add-ons & Links / J/Link / Part 2. Writing Java Programs That Use Mathematica /

2.13 Using Loopback Links

In addition to the MathLink and KernelLink interfaces, there is one other link interface: LoopbackLink. Loopback links are a feature of MathLink that allow a program to conveniently store Mathematica expressions. Say you want to read an expression off a link, keep it around for awhile, and then write it back onto the same or a different link. How would you do this? If you read it with the standard reading functions (getFunction(), getInteger(), and so on), you will have broken the expression down into its atomic components, of which there might be very many. Then you will have to reconstruct it later with the corresponding series of "put" methods. What you really need is a temporary place to transfer the expression in its entirety, where it can be read later or transferred again to a different link. A loopback link serves this purpose.

Before we go on to examine loopback links, please note that J/Link's Expr class is used for the same sorts of things that a loopback link is used for. Expr objects use loopback links internally, and are a much richer extension of the functionality that loopback links provide. You should consider using Expr objects instead of loopback links in your programs.

If a MathLink is like a pipe, then a loopback link is a pipe that bends around to point back at you. You manage both ends of the link, writing into one "end" and reading out the other, in FIFO order. To create a loopback link in J/Link, use the MathLinkFactory method createLoopbackLink():

// In class MathLinkFactory:

public static LoopbackLink createLoopbackLink() throws MathLinkException;

The LoopbackLink interface extends the MathLink interface, so all the MathLink methods can be used on loopback links. LoopbackLink adds no methods beyond those in the MathLink interface. Why have a separate interface then? It can be useful to have a separate type for this kind of MathLink, because it has different behavior than a normal one-sided MathLink. Furthermore, there is one method in the MathLink interface (transferToEndOfLoopbackLink()) that requires, as an argument, a loopback link. Thus, it provides a small measure of type safety within J/Link and your own programs to have a separate LoopbackLink type.

You will probably use the MathLink method transferExpression(), or its variant transferToEndOfLoopbackLink(), in conjunction with loopback links. You will need transferExpression() either to move an expression from another link onto a loopback link or to move an expression you have manually placed on a loopback link onto another link. Here are the declarations of these two methods:

// In the MathLink interface

void transferExpression(MathLink source) throws MathLinkException;

void transferToEndOfLoopbackLink(LoopbackLink source) throws MathLinkException;

Note that the source link is the argument and the destination is the this link. The transferExpression() method reads one expression from the source link and puts it on the destination link, and the transferToEndOfLoopbackLink() method moves all the expressions on the source link (which must be a LoopbackLink) to the destination link.

We already mentioned a common case where loopback links are convenient—temporary storage of an expression for later writing to a different link. This is done more simply using an Expr object, however (Section 2.14). Another use for loopback links is to allow you to begin sending an expression before you know how long it will be. Recall that the putFunction() method requires you to specify the number of arguments (i.e., the length). There are times, though, when you don't know ahead of time how long the expression will be. Consider the following code fragment. We need to send a list of random numbers to Mathematica, the length of which depends on a test whose outcome cannot be known at compile time. We can create a loopback link and push the numbers onto it as they are generated, counting them as we go. When the loop finishes, we know how many were generated, so we call putFunction() and then just "pour out" the contents of the loopback link onto the destination link. In this example, it would be easy to store the accumulating numbers in a Java array or Vector rather than a loopback link. But if we were sending complicated expressions it might not be so easy to store them in native Java structures. It is often easier just to write them on a link as you go, and leave the storage issues up to the internals of MathLink.

// Here we demonstrate sending an expression (a list of reals)

// whose length is unknown at the start.

try {

    ...

    LoopbackLink loop = MathLinkFactory.createLoopbackLink();

    int count = 0;

    while (someTest) {

        loop.put(Math.random());

        count++;

    }

    ml.putFunction("List", count);

    ml.transferToEndOfLoopbackLink(loop);

    loop.close();

    ...

} catch (MathLinkException e) {}