How to preventing short-circuiting?
Asked Answered
S

2

5

suppose i have two functions, boolean fA() and boolean fB()

if i write another function function(boolean b) and I call function(fA()||fB()) then fB() might not be executed, if fA() returns true.

I like this feature, but here I need both functions to execute. Obvious implementation:

boolean temp = fA();
function(fB()||temp);

is ugly, and needed extra line makes it less readable.

is there an way to force evaluation in Java or other elegant way to write this in one line without helper variable?

Submit answered 22/4, 2014 at 14:40 Comment(6)
This question should be called "preventing short-circuiting" I think.Bornholm
Note: It might look better to you, but for new readers it will certainly hide your intentions.Rihana
@Bornholm yeah, that is better.Kooky
Why do you want the second function to run? Is it because of some side-effect it has? If it is - and if you can - you might want to consider separating the predicate (boolean returning) part of fB() from the side effect (e.g. updating some other object, logging, whatever). If I later came across your code I would almost certain change it back to the short-circuiting version (or change | back to ||); unless the method names or content made it clear this was the wrong thing to do.Gelb
I'd recommend you to not mess around with things like "preventing short-circuiting". This functionality should be worth 3 lines of code that are clear and readable and where the intention (namely, that both functions should always be called) becomes obvious.Tannen
@Gelb they are actually all the same function (fb, fa, function). I have tree structure (when each nod has no more than two subtrees) and I need this function to be executed on all leafs, and i need to know if it were at least once successful (with certain result). But i need it to execute on each leaf nevertheless. so in fact my problem is recursive call on non-leaf nodes. I don't really think that i can separate those into two functions.Kooky
H
13

You can use | instead, it doesn't do short-circuit evaluation:

function(fB() | fA());

This ensures that even if fB is true, fA will be called.

Homonym answered 22/4, 2014 at 14:41 Comment(8)
that is genius. thanks. now I just need to wait 13 mins before accepting your answer.Kooky
I'm not sure this is genius. To many programmers this will look like a straight typo (which they might later 'fix'). | is generally used in the context of manipulating bit strings/flags. If this isn't such a case you are probably better off with the longer (multi-line) version plus a comment.Gelb
@Gelb | is meant to use in these cases. Classic example where it should be used.. is this case. Your comment misleads OP, if a programmer will think it's typo, he better not be programming.Homonym
I've been a Java programmer for a long time. I've never used | on boolean values (on the bit strings of byte, short, int, long - yes: but never on booleans). To me this sounds like a classic case of failure of separation of responsibilities in fB() and perhaps in fA() too: since the fix of swapping the two function calls was not used. (Even if swapping them did work, that would still be subtle and obscure.)Gelb
BTW. What do you mean by 'OP' in this context?Gelb
@Gelb Original Poster :)Homonym
@Gelb Organisation of Islamic Cooperation? ;)Homonym
@Gelb I agree with Maroun that this is fairly standard (and you can always add a comment if it makes you feel uncomfortable).Bounce
W
1

You are attempting to write some clever code. This will hurt the long term maintainability and may lead to people trying to 'fix' your clever code and break it.

The correct thing to do is to write it simply and clearly what you are doing:

boolean val = false;
val |= fA();
val |= fB();
function(val);

There is no question what the parameter val is, or if fB() is being called when fA() return false. The code may take up a few more lines than other clever versions, but it is clear and concise and shows exactly what it is doing and intends to do in a way that does not suggest to someone some other functionality.

Whyalla answered 25/4, 2014 at 19:4 Comment(1)
In fact you are relying on the no-short-circuit evaluation here. It's based on the fact that val |= fA() translates to val = val | fA(), but not to val = val || fA(). The expression val |= fA() also raises the question whether fA() will be evaluated at all if val is already false.Extracanonical

© 2022 - 2024 — McMap. All rights reserved.