Day 161, and the Case of the Mysterious Return

Part of HMH's fun is trying to anticipate how Casey is going to write something before he writes it, and improving at this challenge over time.

But the return type of MergeIfPossible() in day 161 really threw me.

Recap: The function initially returned the result of the merge -- a pointer to the block header, whether a merge happened or not. But then Casey changed his mind and changed it to a bool, meaning that a little bit of work needed to be done after the function returned in the case of a successful merge.

What made the bool return appealing here?
If MergeIfPossible() returns the pointer to the merged block when the merge succeeds, what should it return if the merge fails?
NULL?
If the merge doesn't happen it would just return the original block pointer.
I don't generally look at the code off-stream, so I'm just going by memory here:

My suspicion is that I realized that I wouldn't know which pointer to return in the case of a non-merge, so I couldn't have gone:

1
2
Block = MergeIfPossible(Prior, Block);
Block = MergeIfPossible(Block, Next);


Which is what I actually wanted to write. I couldn't do this because someone has to do the test, since MergeIfPossible needs to make sure it returns the free block in a non-merge case, which would require checking the flag explicitly and remember which one was free (maybe that can be slipstreamed into the work, I don't remember).

What I am realizing now that I have more time to think about it, is that you probably could be Mr. Sly Pants and do this instead:

1
2
Block = MergeIfPossible(Prior, Block);
MergeIfPossible(Block, Next);


Now you just write MergeIfPossible to always return the second parameter if no merge happened, and the merged block if it did, and that "just works", right... so that's another thing I could have done. I think I probably like it the way it is now, though, because it's clearer what's going on in both functions, actually.

- Casey
Well, I could see it returning the merged block and if it could not merge the empty block (of witch there is only one). If they are both not empty, one could simply return the either as one should not call the function then. that way one could also just pass in the block and let the function look at both its next and its previous. That was my first thought as one probably always wants to merge both cases. Or do i miss something there?
I think omgagiantrock is thinking along the lines of what I was thinking.

Essentially, in the place it was being used, we always has one _known_ free block and we were trying to merge it with another block that might or might not be free. So this is what I assumed would be the approach:

1
2
Block = MergeIfPossible(Block, Prior);
Block = MergeIfPossible(Block, Next);

Where, if a merge didn't happen, it would always return the known free block, ie the first argument "Block".

So I think I see where my confusion lay now. I saw it as "merge this known free block with this block of unknown status" whereas Casey was writing the function as "merge these two blocks if they can be merged". In the latter case, the function doesn't assume that the first arg IS a free block.

Happy to have that cleared up. Danke.
Well the problem there is that MergeIsPossible needs to check to see if the blocks are contiguous, and if you pass them the way you're doing it now, then it would have to check both directions to see if the merge is possible, instead of just the forward direction. You know?

- Casey
Yeah, I see what you mean. bool wins.