On 22 September 2014 13:19, Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
On 9/21/2014 4:27 AM, Manu via Digitalmars-d wrote:
It's also extremely hard to unittest; explodes the number of static if paths
exponentially. I'm constantly finding bugs appear a year after writing some code
because I missed some static branch paths when originally authoring.

If you throw -cov while running unittests, it'll give you a report on which code was executed and which wasn't. Very simple and useful.

It is a useful tool, but you can see how going to great lengths to write this explosion of paths is a massive pain in the first place, let alone additional overhead to comprehensively test that it works... it should never have been a problem to start with.

You may argue that I didn't test my code effectively. I argue that my code should never have existed in the first place. It's wildly unsanitary, and very difficult to maintain; I can rarely understand the complexity of ref handling code looking back after some months.

This was my very first complaint about D, on day 1... 6 years later, I'm still struggling with it on a daily basis.

Here's some code I've been struggling with lately, tell me you think this is right:
https://github.com/FeedBackDevs/LuaD/blob/master/luad/conversions/functions.d#L286 <- this one only deals with the return value. is broken, need to special-case properties that receive arguments by ref, since you can't pass rvalue->ref
https://github.com/FeedBackDevs/LuaD/blob/master/luad/conversions/functions.d#L115 <- Ref!RT workaround, because I need a ref local
https://github.com/FeedBackDevs/LuaD/blob/master/luad/conversions/functions.d#L172 <- Ref!T again, another instance where I need a ref local
https://github.com/FeedBackDevs/LuaD/blob/master/luad/conversions/functions.d#L180
https://github.com/FeedBackDevs/LuaD/blob/master/luad/stack.d#L129 <- special case handling for Ref!T that I could eliminate if ref was part of the type. Note: 3rd party code never has this concession...
https://github.com/FeedBackDevs/LuaD/blob/master/luad/stack.d#L448 <- more invasion of Ref!, because getValue may or may not return ref, which would be lost beyond this point, and it's not practical to static-if duplicate this entire function with another version that returns ref.
https://github.com/FeedBackDevs/LuaD/blob/master/luad/stack.d#L157 <- special-case function, again because ref isn't part of the type
There are many more instances of these throughout this code.

This is just one example, and not even a particularly bad one (I've had worse), because there are never multiple args involved. These sorts of things come up on most projects I've worked on.
The trouble with these examples, is that you can't try and imagine a direct substitution of the static branches and Ref!T with 'ref T' if ref were part of the type. This problem has deeply interfered with the code, and API concessions have been made throughout to handle it. If ref were part of the type, this code would be significantly re-worked and simplified. There would probably be one little part somewhere that did logic on T, alias with or without 'ref' as part of the type, and the cascading noise would mostly disappear.

Add to all of that that I still can't pass an rvalue to a ref function (5 years later!!) >_<

It's also worth noting that, with regard to 'ref', the above code only _just_ suits my needs. It's far from bug-free; there are places in there where I was dealing with ref, but it got so complicated, and I didn't actually make front-end use of the case in my project, that I gave up and ignored those cases... which is not really ideal considering this is a fairly popular library.

I have spent days trying to get this right. If I were being paid hourly, I think I would have burned something like $2000.