Short-circuit evaluation?

Mar 2, 2010 at 2:11 PM

Does Jint support short-circuit evaluation?  As in, if I evaluation "MyObj.SomeProperty == undefined && MyObject.ThrowExceptionIfSomePropertyIsUndefined()", will the right-hand side get evaluated?

Jint.JintEngine engine = new Jint.JintEngine();
engine.SetFunction("FooT", new Func<Boolean>(delegate() { Console.Out.WriteLine("Returning True!"); return true; }));
engine.SetFunction("FooF", new Func<Boolean>(delegate() { Console.Out.WriteLine("Returning False!"); return false; }));
Console.Out.WriteLine(((Boolean)engine.Run("FooT() && FooF()")) ? "Got true!" : "Got false!");

Gets me

Returning True!
Returning False!
Got false!
Press the [Any] key to continue.
Is there a switch to get short-circuit evaluation to work?

Coordinator
Mar 2, 2010 at 2:12 PM

I need to correct it, give me five minutes.

Coordinator
Mar 2, 2010 at 2:19 PM

Well actually the behaviour you describe is ok ! FooT() && FooF() needs to call FooF() !
I have added some unit tests and they are ok also.

Mar 3, 2010 at 7:14 PM
Edited Mar 3, 2010 at 7:14 PM

According to Wikipedia (http://en.wikipedia.org/wiki/Short-circuit_evaluation), JavaScript supports short-circuit evaluation for && and ||.  Perhaps Wikipedia is not accurate.  My understanding is that FooT() && FooF() should only call FooF() if FooT() evaluates to true.  That way, you can do something like:

 

if(CanICallFoo() && CallFoo())
{
    return "CallFoo is true!";
}

return "CallFoo is false!";

 

And not have to worry about the error generated by CallFoo when CanICallFoo evaluates to false.

Thanks again for the excellent tool!

    Don

Mar 3, 2010 at 8:04 PM

Hi Don,

> My understanding is that FooT() && FooF() should only call FooF() if FooT() evaluates to true.

This is correct, in your first code snippet FooT() is evaluating to true, which is why FooF() gets called!

Cheers,

Tom

Coordinator
Mar 4, 2010 at 4:40 AM

Hi all,

The short-circuit evaluation works with the version on the svn repository. However, from the code written above, this is obvious that the FooF() will be called since FooT() always returns true. This is what Sébastien meant.

 

Mar 4, 2010 at 1:54 PM

Pardon me for the ebkac!  With copying and pasting and copying and pasting, I transcribed my example incorrectly.

How can I get the SVN copy?  The version I'm using (0.8.8.0) doesn't work for the example below:

Func<Boolean> FooT = new Func<Boolean>(delegate() { Boolean b = true;  Console.Out.WriteLine("+-FooT => {0}!", b); return b; });
Func<Boolean> FooF = new Func<Boolean>(delegate() { Boolean b = false;  Console.Out.WriteLine("+-FooF => {0}!", b); return b; });
engine.SetFunction("FooT", FooT);
engine.SetFunction("FooF", FooF);

String[] expressions = {
    "FooT() && FooF()"
  , "FooT() || FooF()"
  , "FooF() && FooT()"
  , "FooF() || FooT()"
};

foreach (String expression in expressions)
{
    Console.Out.WriteLine("{0}:", expression);

    Boolean result = (Boolean)engine.Run(expression);
    Console.Out.WriteLine("+-> {0}", result);
}

Output:

 

FooT() && FooF():
+-FooT => True!
+-FooF => False!
+-> False
FooT() || FooF():
+-FooT => True!
+-FooF => False!
+-> True
FooF() && FooT():
+-FooF => False!
+-FooT => True!
+-> False
FooF() || FooT():
+-FooF => False!
+-FooT => True!
+-> True
Press the [Any] key to continue.
Mar 19, 2010 at 2:54 PM

Sorry, I didn't see this thread when I started my discussion thread and added an issue. Yes, I have problems with 0.8.8 too, but haven't looking into svn.