Possible history table improvement

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

AlvaroBegue
Posts: 931
Joined: Tue Mar 09, 2010 3:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: Possible history table improvement

Post by AlvaroBegue »

hgm wrote:
lucasart wrote:Now I'm very careful with C operators. Mistying a '&&' into a '&', or making wrong assumptions about operator precednece and default associativity, has cost me quite a few hours of debugging already.
I use & and | in stead of && and || quite often. This can save you branches, and branches that are not there can also not be mispredicted.
Hmmm... I would rather make the intent obvious by using && and || for booleans and & and | for bitwise operations, and let the compiler figure out how to save the branch, if it is a good idea. Compilers are pretty smart these days.
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Possible history table improvement

Post by lucasart »

Harald wrote:And when I wrote that I thought that & had a higher priority than <.
That was also wrong. We learn: Just use a lot of () and be careful with & in conditions.
The C operator precedence table is way too big and complex to fit in my brain. I never try to learn and remember it, but accept that I do not want to remember it. If I did learn it off by heart, I would be too tempted to write obscure code, by abusing my knowledge of it, which is not a good thing.

I only remember the stuff that I use most often, and the rest (un-obvious) I prefer to use () to (i) be sure it works (ii) make the code more self-obvious.

But sometimes I read other people's code, and some people love to abuse their knowledge of C operator precedence to write obscure code. So I just Google for "C operator precedence".

For example, I've noticed that Marco likes to use the right-to-left associativity of the ternary operator '? :' to chain conditions (and save lines of code) like this:

Code: Select all

a = b ? c &#58; d ? e &#58; f;
which is equivalent to

Code: Select all

a = b ? c &#58; &#40;d ? e &#58; f&#41;;
I learnt this 'trick' reading stockfish, but I prefer not writing code like that, as it takes too much brain power to read.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
AlvaroBegue
Posts: 931
Joined: Tue Mar 09, 2010 3:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: Possible history table improvement

Post by AlvaroBegue »

lucasart wrote:For example, I've noticed that Marco likes to use the right-to-left associativity of the ternary operator '? :' to chain conditions (and save lines of code) like this:

Code: Select all

a = b ? c &#58; d ? e &#58; f;
which is equivalent to

Code: Select all

a = b ? c &#58; &#40;d ? e &#58; f&#41;;
I learnt this 'trick' reading stockfish, but I prefer not writing code like that, as it takes too much brain power to read.
The rules of C are the way they are for a reason. Well, sometimes it's a bad reason. But in the case of the ternary operator, you can read concatenated ternary operators as "if this is true, this value; otherwise if this other thing is true, this other value, etc.". It's as easy to read as an if-else if-...-else block.
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Possible history table improvement

Post by lucasart »

AlvaroBegue wrote:
lucasart wrote:For example, I've noticed that Marco likes to use the right-to-left associativity of the ternary operator '? :' to chain conditions (and save lines of code) like this:

Code: Select all

a = b ? c &#58; d ? e &#58; f;
which is equivalent to

Code: Select all

a = b ? c &#58; &#40;d ? e &#58; f&#41;;
I learnt this 'trick' reading stockfish, but I prefer not writing code like that, as it takes too much brain power to read.
The rules of C are the way they are for a reason. Well, sometimes it's a bad reason. But in the case of the ternary operator, you can read concatenated ternary operators as "if this is true, this value; otherwise if this other thing is true, this other value, etc.". It's as easy to read as an if-else if-...-else block.
I don't advocate not using '?:' or arbitrarly limiting ourselves to not chain the ternary operator. All I'm saying is that chaining '?:' without () is a bit obscure (in reality a,b,c,d,e,f are more complex expressions...). So I simply prefer

Code: Select all

a = b ? c &#58; &#40;d ? e &#58; f&#41;;
to

Code: Select all

a = b ? c &#58; d ? e &#58; f;
I would never change my chained '?:' for ugly spaghetti if/else blocks. Heaven forbid! Imagine writing the abode one-liner in Pascal with all the begin/end cruft (just the thought gives me nausea already).

Some people think that () should be put everywhere to avoid mistakes.

Code: Select all

a = (&#40;b&#41; ? &#40;c&#41; &#58; (&#40;d&#41; ? &#40;e&#41; &#58; &#40;f&#41;));
Clearly these people are stupid, but they exist...
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
AlvaroBegue
Posts: 931
Joined: Tue Mar 09, 2010 3:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: Possible history table improvement

Post by AlvaroBegue »

lucasart wrote:Some people think that () should be put everywhere to avoid mistakes.

Code: Select all

a = (&#40;b&#41; ? &#40;c&#41; &#58; (&#40;d&#41; ? &#40;e&#41; &#58; &#40;f&#41;));
Yeah, those people write in LISP. :)

I think chaining ternary operators without parentheses is actually preferable. It allows you to do things like this:

Code: Select all

bool operator<&#40;SomeStruct a, SomeStruct b&#41; &#123;
  return a.first != b.first ? a.first < b.first
       &#58; a.second != b.second ? a.second < b.second
       &#58; a.third != b.third ? a.third < b.third
       &#58; a.fourth != b.fourth ? a.fourth < b.fourth
       &#58; a.fifth < b.fifth;
&#125;
If you add parentheses to that you'll just mess things up.