Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

What is the simplest way to throw away all expressions waiting to be read on a loopback link, effectively resetting the link?

I am building an expression on a loopback link using the C MathLink interface. If the operation succeeds, I want to send the expression to stdlink. If it fails, I need to clear the loopback link. What is the recommended way to do this?

share|improve this question
    
Can't you just call MLClose on your current loopback link and then open a new loopback link? –  Leonid Shifrin Jan 28 '13 at 8:23
    
Have you tried what happens when you pass NULL as dst in MLTransferToEndOfLoopbackLink? Apart from that it seems there is no way to clear a LoopbackLink. @ToddGaylay can you reveal what you would do? –  halirutan Jan 28 '13 at 9:38
    
Did you mean @Todd Gayley ? (yes, youd did) –  Yves Klett Jan 28 '13 at 15:40
    
@YvesKlett Yes and oops, I see my typo now. Thanks. –  halirutan Jan 28 '13 at 15:50
    
@Leonid I think I can, but I never went into MathLink this deep, and I was hoping for some reassurance that this is the "right" way to do it (i.e. how a loopback link was really meant to be used). –  Szabolcs Jan 28 '13 at 16:31
show 1 more comment

1 Answer

up vote 8 down vote accepted

Using NULL as the destination link, as in MLTransferExpression(NULL, loop); is indeed the "correct" way to do this.

One small caveat: You cannot use that technique if you have not built a complete expression on the loopback link. For example, if you are building a complicated expression on the loopback link bit by bit, then decide halfway through to bail out and not use the result you have been building, then you would just want to close the loopback link to discard it. A simple example:

// Promise to put 100 elements:
MLPutFunction(loop, "List", 100);
int succeeded = TRUE;
for (int i = 0; i < 100; i++) {
    ...
    if (someTest) {
        succeeded = FALSE;
        // Bail out before putting all 100 promised elements.
        break;
    } else {
       MLPutInteger(loop, someInt);
    }
}

if (succeeded) {
    MLTransferExpression(stdlink, loop);
} else {
    // *** BAD ***  Haven't put a complete expression on the link,
    // so this will not work to drain the link:
    MLTransferExpression(NULL, loop);
    ... send different result on stdlink
}

If you are doing something like the above, it's better to accumulate the parts of the final expression on the link as separate expressions, then wait until the loop is done to build the final expression:

int count = 0;
for ( ; count < 100; count++) {
    ...
    if (someTest) {
        break;
    } else {
       MLPutInteger(loop, someInt);
    }
}

if (count == 100) {
    // Loop ran to completion; send a list containing all the elements
    // that were stored on the loopback link.
    MLPutFunction(stdlink, "List", 100);
    MLTransferToEndOfLoopbackLink(stdlink, loop);
} else {
    ... send different result on stdlink
}

In this way, you never have a partial expression on the loopback link.

But you can avoid all these considerations by simply opening and closing your loopback link every time your function is called. This could have an impact on performance if your function runs very quickly and is called many times. It costs about .00001 seconds on my machine to open and close a loopback link.

share|improve this answer
1  
It sounds like I need to close/open the link then because I have half-built expressions. The performance hit is acceptable in this case. –  Szabolcs Jan 28 '13 at 20:38
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.