Please implement Short-Circuit evaluation for Blueprint

Blueprint scripting has no Short Circuit this is bad when I am doing AND evaluation for multiple pure functions.
I hope Epic could implement it.

For those who are not sure,
Short Circuit is a term used to describe situation where :

If you evaluate Cond1 AND Cond2 . If Cond1 fails , Cond2 does not get run at all.
Which is a common knowledge for programmers.

Need more explanation on this really
 do you have a screenshot of the Blueprint or code snippet you’re talking about? AFAIK, Blueprint Pure functions get run only if you ‘call’ them by plugging the output into something. If the output isn’t requested, it won’t run at all.

What he means is this:


if(evaluateStuff() && evaluateMoreStuff()) {
...
}

If evaluateStuff() returns false, the whole if clause is evaluated to false. Usually in most (if not all) mainstream languages the evaluateMoreStuff() function wouldn’t be called at all since there is no need to. What means is that in blueprints the second operand is evaluated also, as in evaluateMoreStuff() is called even though the first operand (evaluateStuff()) returned false.

This is problematic because without short circuiting conditional evaluating you can’t do following for example:



Pseudo code
List mylist = getList();
If(mylist != null && !mylist.isEmpty()) { //error, trying to call isEmpty() on null variable
                                                           //if mylist is null and expression doesn't short circuit

}


i dont understand what is short circuit
but i found is select node still get all data even if dosnt need to be called.
like here, interface get health would be called and would spam warnings in output log like crazy until character not created.

Yeah I see, so if the function returns NULL instead of True or False, you want the statement to return false?

The more obvious example is with a pointer:



SomeType* Ptr = GetSomeObject();

if (Ptr && Ptr->DoSomeMethod())
{
  // do something
}


Without short circuiting you’ll get a classic memory violation error.

Well, Blueprint handles this gracefully anyway right? For example it doesn’t crash if you try to access an out-of-bounds element of an Array, it just warns you instead. In the case of Pointers, you can just do ‘IsValid’ and follow one execution path or a different one.

I could be wrong but it just seems like a workaround for possibly dodgy code? If you didn’t want to check the pointer because you never want it to NOT be valid at that point, you just trigger an Assertion instead right? There is already an Is Valid PURE function in BP that returns a bool too, so you just plug that into one AND and whatever else into the other right?

I dunno, maybe I’m missing something.

Those are single examples of the problem. The real problem is that the boolean expression operands might cause side effects even if they’re pure or not and people are (rightfully) assuming that they are evaluated in a similar short-circuiting way as normal C++ code. I assumed it works that way and I’m guessing I’m not the only one.

type AND you will get AND node.

I think people don’t understand very well what is happening there
 Here is probably best example in pseudo code:

When you call function TestShortCircuit in C++ your output log will be:

When you construct same condition using blueprint node your log will be:

because blueprint is probably not wise enough to detect that condition can never be true when first function (A) returned false.

I belive it is “by design” because Epic doesn’t like forcing people to take care of order of input pins for pure functions
 But yes, some AND node with Short Circuit implemented will make conditions nicer and life will be easier! :slight_smile:

2 Likes

cmon guys, even i got the idea =)

Yeah I see what you’re saying now, though technically, it’s still possible just with a longer ‘chain’ of nodes. But yeah kind of annoying then


here’s a better way of explaining it.

1)It has nothing to do with stability or crashing.
2) Very applicable if you extensively use ‘Pure’ Functions ( I do ) , ‘Non-Pure’ functions will run regardless when exec nodes are hit.
3) This solves a lot of Accessed ‘None’ spamlogs. Chasing them down isn’t fun.

*forgive my spelling and typos. I’m using paint and i’m too lazy to remake the pic

2 Likes

Wow I thought this happened by default in BP never actually tested this.

+1 this.

It means you can prioritize those conditions so Condition 1 is the Condition that will most likely be false and if this is the case stop executing further code. Like you say Branch is the easiest way round this but It soon begins unorganized and, illogical.

Uh this is already supported, you just stagger the branch nodes. Do x then if true do y. I thought this was the intended workflow for that in BP.

Regardless c++ is by standard a short circuiting language. since BP is written in c++ you’d think that it would be SC’d as well, can you provide proof it isnt SC’ing ?

I wonder if SC was overridden for BP so that there are no errors in branch prediction.

Because it seems like blueprint works on the surface as such that each node is its own function and they try to safely acquire all data needed for said function before execution, which would answer why both get looked at (i honestly have no idea)

Blueprint runs on virtual machine, tt’s something that virtual machine needs to support or it something that need to be node class.

@SaxonRah yeah I’m away you can just stack the branch , but it seems counterintuitive to have AND node and ended up having to do that.

BTW , I can confirm it doesn’t short circuit surely. Just do an AND node with 2 pins. Put false at the top one. Connect the second to a pure function that returns boolen . In the pure function , just do print string. You’ll see the string printed , which should not , because if the first pin is false , the second one must not be evaluated.

I think it is to be noted that , This is an optimization for an OR as well. Meaning , if the first one is true , the rest should NOT be evaluated.

Jesus christ, is the OP’s simple point really so hard to understand or is it common to simply not read messages before posting here? He clearly statet what’s the problem, he made examples, he even linked the wikipedia article. It’s that simple:
If the first condition is false already, Blueprint shouldn’t even evaluate the other pins connected to an AND node. That’s not only more elegant for null-checks etc., it’s way faster, too (for obvious reasons.)

And yes, it would be great if BP would behave this way.

The reason i said i thought it was the intended workflow is that im quite sure that kismet worked like this too. Where it would check both regardless. I could be mistaken.

You’re right it doesn’t SC. Which would imply its programmed like this for a reason, I’ll try and look up the code for the nodes and see if anything is specifically said so.

So the nodes are quite simple they literally just say “return A && B;” and “return A || B;” Which is weird because both && and || are short-circuiting by c++ standard. The only way to get a non SC OR / AND is by using the + for OR and * for AND in c++ Which is actually Boole Algebra
 but you get the desired functionality of non SC checks.

:frowning: Can i get a much more experienced Epic Developer to tell me why this is happening ? I’m so freaking confused as to why this happens, and im really interested as to how you’ve done this.

Operator overloading somewhere perhaps ?

Actually I wonder if the arguments passed to the OR and AND nodes are function calls and they are executed first thus the short circuiting is basically useless because you’ve seen the results of the functions before you checked the returns.