The Life of a Programmer

Why more eyes are helpful: time wasted on a simple bug

I spent several hours trying to fix a defect that didn’t exist. I’m working on template methods in Leaf and one of my overloads wasn’t resolving. As it is a new feature I had every reason to believe it wasn’t working correctly. But it was. If I had a team member just glance at the code they would have found it quite quickly.

The Code

The problem was with this unit test (written in Leaf):

1
2
3
4
5
6
7
8
class pine {
    func cone = (x)->() member {
        trace(x+1)
    }
}

var p : pine
trace( p.cone(3) )

This follows the pattern of several other parametric tests. My compiler kept saying it couldn’t find a match for trace. Since I was working on class parametrics I assumed the first trace was the problem. This was reinforced by what I thought was a nearly equivalent test case that worked. It merely lacked the member marker, which should have no influence on the trace matching here.

1
2
3
4
5
6
7
8
class pine {
    func cone = (x)->() {
        trace(x+1)
    }
}

var p : pine
p.cone(3)

At this point, even though I know you don’t know Leaf, you’ve probably already spotted the problem. If you were sitting beside me you’d wonder what all the stress was about.

Nothing misleading

The error my compiler emitted is no-matching-symbol. This happens when there is an overloaded function, like trace, but it can’t figure out which version to call.

The error also includes the parameter types it is attempting to match: ( : ( ) ). This type is perhaps not clear, so for comparison the type I was hoping for is a parameter list of one integer: ( : integer ). Instead I was getting an empty tuple, the equivalent of void in other languages.

I let myself get totally mislead here. An incorrect type is something I’d expect from an error in my template code. An empty tuple was unexpected, but I completely ignored that detail.

My attempts to fix the problem were going nowhere. I added more test cases and refactoring little bits of code. But nothing helped. I even took a long bike ride at some point.

The line number

I’m not even sure now how I noticed it was the second trace causing the problem. Something must have just clicked at some point.

When I encounter such problems I usually resolve to improve future debugging. Leaf’s error messages are quite cryptic now, so I quickly blamed that. It should have emitted a line number and then I could have seen immediately where the problem was…

1
Source: share/unit_tests/block/parametric/function/class_member_simple.lfb:8,1

…okay, so it did emit a line number. So yes, a fresh set of eyes would have spotted the error almost immediately. But take this as a warning. The next time a colleague asks you to help them with an error, try to understand the problem on your own first. If you had let me explain this problem first, you’d also just get stuck in the same room chasing shadows with me.

Please join me on Discord to discuss, or ping me on Mastadon.

Why more eyes are helpful: time wasted on a simple bug

A Harmony of People. Code That Runs the World. And the Individual Behind the Keyboard.

Mailing List

Signup to my mailing list to get notified of each article I publish.

Recent Posts