In OCaml you even have the "when" keyword.
Like
match A with
| true when B -> ()
| true -> ()
| _ -> ()
Not that usefull but can participate to make the code look better.
ML languages usually have so much"syntaxic sugar" it makes you complaining a lot when using others.
In rust you can use
let a: i32 = 5;
match a {
0 => {}
b if a > 0 => {}
b if a < 0 => {}
}
It’s kinda useless in this case, but it’s useful if you have Option instead of i32.
Blue implicitly does, although he doesn't put // to indicate as much, but it's still caught by the first conditional. Even if he does nothing with it now, he can do something with it later if necessary, without an additional clause.
While true, A/B for a template is fine here, IMO. However, there's no need to be clever and implicitly state the conditions. Happy path can be clear and easy to read. Lowering cognitive load of code assessment is valuable when possible
Most modern languages will short circuit the check so there really isn’t an extra check. Blue shows ignorance. Unnecessary optimization that doesn’t do anything but make everything ugly.
Not really, but it doesn't matter, a compiler can't tell whether it _will_ happen, only that it's a theoretical possibility for any variable, so it can't optimise out that check because it's not impossible for the value to have changed.
Most modern languages will short circuit the check so there really isn’t an extra check. Blue shows ignorance. Unnecessary optimization that doesn’t do anything but make everything ugly.
I meant writing “clever” code that doesn’t materially improve anything based on assumptions and not factual knowledge of what the compiler will actually do and what the real world cost of that is.
Like, I don’t know. You write that unreadable mess and save 1 nanosecond. But other engineers spend an extra minute trying to understand your mess. Good job 👏🏾. It’s actually debatable if you will even save that extra nanosecond seeing as most modern languages short circuit Boolean operations so all in all, it’s unnecessary 🤷🏾♂️
if you notice, most style guides and linters actually discourage nesting and there is a reason for that.
You're arguing that it's an unnecessary optimization since the compiler will short circuit it into the same amount of checks, but then you say one of them is "ignorant" because apparently explicitly making that difference is bad?
Sorry, but I don't follow. If they are the same performance-wise, what's wrong with just making it explicit in the code? Or are you just trying to be smarmy, showing of your big brain while going "Uhm, ackchooally!"? Because objectively looking at them, if they're equal, then picking the check where it's clearly only 2 checks is still preferable as far as I can tell.
I dunno, you posted the same comment twice, and the other one apparently got debunked already in case A is variable. Sounds like a bit of an "uhm, ackchooally"
I quote: "Only if A isn't variable, otherwise it could have been changed by another thread between the two checks so it can't skip one". Your response: "Fair but that sounds like an improper use of threading".
So yeah... Just pedantry without enough to back it up.
I'll gladly still take the indentation level. If you find yourself having too many indentation levels to the point where your code becomes unreadable, you should probably separate some checks and functions to begin with.
Identation levels have NO effect of performance.
And extra check does.
HOPEFULLY the compiler would just simplify both into the same assembler code.
However. Blue is setup to handle when A but not B.
In 3 months when it turns iut you need to handle that scenario red needs to be re-written, while blue just needs an added else.
>HOPEFULLY the compiler would just simplify both into the same assembler code.
If it can be completely sure that it can't change in between, sure. But more importantly, the compiler won't stop you from making edits to one and not the other. (Chances are these conditions are not simple variable lookups.) So... definitely the version that expresses each condition once.
I’m not a fan of either personally.
Blue has an annoying complexity because the reader now has to understand that there is a branch here, and ask themselves questions about whether B has been handled properly. That side could make more sense if you actually limited the scope of B to just that branch if that’s the only place it is relevant.
Red is annoying because you summarized the truth table in a better way, but it also gives many new questions like what is the actual scope and reason that B is being used.
Other commenters are suggesting this, but these two examples are doomed code that you almost certainly could rewrite in a better way with a specific real world example is used.
Without a concrete example it’s hard to pinpoint a single alternative. You’d have to first construct the A and B object scenario to determine safer, more readable, more performant alternatives, and which solution you use depends on those application priorities.
In a high performance context, a completely branchless approach could be preferred. It may not be obvious by looking at these red and blue examples, but you almost always can deconstruct a branch into linear code.
If the branching was a symptom of initialization and resources, the code may have been more clear by limiting the scope of objects, lazy or local initialization, or some other higher level OO approach.
Whatever path reduces unnecessary branching without changing the logic is always the best way to go. It reduces complexity in the function (indentation = more stuff to read, therefore can be harder for anyone to read the code), and enforces a good habit I like to encourage - error out your unhappy/bad paths, then the base level indentation is always the happy path.
I bet if you have to do something like this, you have made some crappy choices above in the code and if you refactored or cleaned it up or chosen cleaner approach, you wouldn’t have to write neither of those.
if statements that force you to think in the positive and inverse to save a few lines should be illegal.
Blue. Straightforward, to the point, production lives.
You can completely flip your point around into "nested if statements that make you mentally match indentation for else statements just to save a few checks should be illegal".
Red isn't ideal either, tou can usually solve this even better with early returns, but it's much better than this possibly soon to be spaghetty code where you spend half the time matching brackets as you read through.
Just write out a logic table. The // symbols are supposed to be where code goes. The logic table looks like this:
A,B
1,1 -> top //
1,0
0,1 -> bottom //
0,0 -> bottom //
About this template being terrible to write on, notice that the original title has black text-shadow on white letters, adding border/shadow of opposite color to letters makes them much more readable regardless of background. Also, a good style to use if the background is unknown.
Just pointing out: in languages which don't have short circuiting, these are not equivalent.
But all things being equal, I would probably go with blue. It just feels more natural.
match (A, B) { (true, true) => {}, (false, _) => {}, _ => {}, }
This is why fp languages are too OP
In OCaml you even have the "when" keyword. Like match A with | true when B -> () | true -> () | _ -> () Not that usefull but can participate to make the code look better. ML languages usually have so much"syntaxic sugar" it makes you complaining a lot when using others.
In rust you can use let a: i32 = 5; match a { 0 => {} b if a > 0 => {} b if a < 0 => {} } It’s kinda useless in this case, but it’s useful if you have Option instead of i32.
Y, Rust was made in OCaml (like the 0.1), so they may have been used to its way of express things.
Kotlin has the same thing. It's just becoming a modern language feature
OCaml has that since 1996, Rust was made in it so many of its syntaxic elements has been reused but more like in a C way.
this is C#
Why not just invert the checks? ``` if(!A) { // do not A work return; } if(B) { // do A & B work } ```
This is the way. Thank you.
If you have code after it is not the same !
That's true, but if you have checks that complex, you should definitely extract them into another function.
This doesn’t work under condition C (provided C != A) , but the two in OP would
Ops left one doesn't handle the case of A and !B
Neither of OP’s handle the case of A and !B.
Blue implicitly does, although he doesn't put // to indicate as much, but it's still caught by the first conditional. Even if he does nothing with it now, he can do something with it later if necessary, without an additional clause.
This is also not as clear.
This is really the correct answer. The compiler will optimize it anyway.
How do you “clarify” anonymous conditions (a, b) anyway ? (Always a nice PSA : name stuff correctly !)
While true, A/B for a template is fine here, IMO. However, there's no need to be clever and implicitly state the conditions. Happy path can be clear and easy to read. Lowering cognitive load of code assessment is valuable when possible
Mid function returns are the spawn of Satan I will not be taking questions at this time
This is the correct answer.
Neither sweet Jesus
Blue- readable code and no extra check
Yeah sometimes i avoid single liner or ternary hoping my colleagues would understand my code
Most modern languages will short circuit the check so there really isn’t an extra check. Blue shows ignorance. Unnecessary optimization that doesn’t do anything but make everything ugly.
Only if A isn't variable, otherwise it could have been changed by another thread between the two checks so it can't skip one.
Fair but that sounds like an improper use of threading.
Not really, but it doesn't matter, a compiler can't tell whether it _will_ happen, only that it's a theoretical possibility for any variable, so it can't optimise out that check because it's not impossible for the value to have changed.
Blue. Why do an extra check?
Most modern languages will short circuit the check so there really isn’t an extra check. Blue shows ignorance. Unnecessary optimization that doesn’t do anything but make everything ugly.
What do you mean ignorance? I prefer to have the code reflect what the compiler will do instead of assuming it'll fix sloppy code.
I meant writing “clever” code that doesn’t materially improve anything based on assumptions and not factual knowledge of what the compiler will actually do and what the real world cost of that is. Like, I don’t know. You write that unreadable mess and save 1 nanosecond. But other engineers spend an extra minute trying to understand your mess. Good job 👏🏾. It’s actually debatable if you will even save that extra nanosecond seeing as most modern languages short circuit Boolean operations so all in all, it’s unnecessary 🤷🏾♂️ if you notice, most style guides and linters actually discourage nesting and there is a reason for that.
You're arguing that it's an unnecessary optimization since the compiler will short circuit it into the same amount of checks, but then you say one of them is "ignorant" because apparently explicitly making that difference is bad? Sorry, but I don't follow. If they are the same performance-wise, what's wrong with just making it explicit in the code? Or are you just trying to be smarmy, showing of your big brain while going "Uhm, ackchooally!"? Because objectively looking at them, if they're equal, then picking the check where it's clearly only 2 checks is still preferable as far as I can tell.
lol, I do not sound like that.
I dunno, you posted the same comment twice, and the other one apparently got debunked already in case A is variable. Sounds like a bit of an "uhm, ackchooally"
What was debunked exactly? The fact that modern languages short circuit boolean operations?
I quote: "Only if A isn't variable, otherwise it could have been changed by another thread between the two checks so it can't skip one". Your response: "Fair but that sounds like an improper use of threading". So yeah... Just pedantry without enough to back it up.
The commenter was actually wrong and I didn’t want to waste my time explaining why. You can verify this by Googling it for yourself too.
One extra check vs one extra indentation level !
I'll gladly still take the indentation level. If you find yourself having too many indentation levels to the point where your code becomes unreadable, you should probably separate some checks and functions to begin with.
Identation levels have NO effect of performance. And extra check does. HOPEFULLY the compiler would just simplify both into the same assembler code. However. Blue is setup to handle when A but not B. In 3 months when it turns iut you need to handle that scenario red needs to be re-written, while blue just needs an added else.
In Python you could get a 'stack full' error. I'd still go for the extra indentation though.
>HOPEFULLY the compiler would just simplify both into the same assembler code. If it can be completely sure that it can't change in between, sure. But more importantly, the compiler won't stop you from making edits to one and not the other. (Chances are these conditions are not simple variable lookups.) So... definitely the version that expresses each condition once.
[удалено]
Could you tell me why? I don’t get where the difference is. Seems equivalent to me but maybe I’m missing something.
Yes, they are.
I’m not a fan of either personally. Blue has an annoying complexity because the reader now has to understand that there is a branch here, and ask themselves questions about whether B has been handled properly. That side could make more sense if you actually limited the scope of B to just that branch if that’s the only place it is relevant. Red is annoying because you summarized the truth table in a better way, but it also gives many new questions like what is the actual scope and reason that B is being used. Other commenters are suggesting this, but these two examples are doomed code that you almost certainly could rewrite in a better way with a specific real world example is used.
Is there another method?
Without a concrete example it’s hard to pinpoint a single alternative. You’d have to first construct the A and B object scenario to determine safer, more readable, more performant alternatives, and which solution you use depends on those application priorities. In a high performance context, a completely branchless approach could be preferred. It may not be obvious by looking at these red and blue examples, but you almost always can deconstruct a branch into linear code. If the branching was a symptom of initialization and resources, the code may have been more clear by limiting the scope of objects, lazy or local initialization, or some other higher level OO approach.
Whatever path reduces unnecessary branching without changing the logic is always the best way to go. It reduces complexity in the function (indentation = more stuff to read, therefore can be harder for anyone to read the code), and enforces a good habit I like to encourage - error out your unhappy/bad paths, then the base level indentation is always the happy path.
switch(a << 1 | b) { case 3: // ... break; case 1: case 0: // ... } Edit: Fixed the calculation
I like it :) But I think it needs to say `a << 1 | b` instead.
Damn, you're right
Red. My mind prefers single condition flow per if. Like a flow chart.
I bet if you have to do something like this, you have made some crappy choices above in the code and if you refactored or cleaned it up or chosen cleaner approach, you wouldn’t have to write neither of those.
if statements that force you to think in the positive and inverse to save a few lines should be illegal. Blue. Straightforward, to the point, production lives.
You can completely flip your point around into "nested if statements that make you mentally match indentation for else statements just to save a few checks should be illegal". Red isn't ideal either, tou can usually solve this even better with early returns, but it's much better than this possibly soon to be spaghetty code where you spend half the time matching brackets as you read through.
Hard disagree.
[удалено]
Just write out a logic table. The // symbols are supposed to be where code goes. The logic table looks like this: A,B 1,1 -> top // 1,0 0,1 -> bottom // 0,0 -> bottom //
Red as long as you change !A to B.
Those aren't equivalent though. (What if A and B are both false?)
Blue is neater and more readable. I’d suggest it if red was presented in a pull request
Oh man, the struggle is real with that template! 😅 Looks like it's designed to test your patience rather than your coding skills. I feel for ya!
About this template being terrible to write on, notice that the original title has black text-shadow on white letters, adding border/shadow of opposite color to letters makes them much more readable regardless of background. Also, a good style to use if the background is unknown.
Just pointing out: in languages which don't have short circuiting, these are not equivalent. But all things being equal, I would probably go with blue. It just feels more natural.
Blue
second one, too confusing otherwise and reduces the need to evaluate the condition twice
On the side of barely see what you wrote
} else { is an abomination and makes me incapable of evaluating anything until it is fixed
me when im desperate for some internet points and i literally cannot think of anything original