Problem
Knowing if and why a thread was canceled requires matching the error message. Golang offers us better tools for this job.
Proposed solution
I propose adding a CancelWithError(error) method to Thread. The provided error is then wrapped in a custom CanceledError that allows callers to understand if and why a thread was canceled using errors.Is/As. By keeping Cancel(string) as is, the library stays backwards compatible.
Related, by default the interpreter calls Cancel with message "too many steps" when the maximum number of steps is hit. I suggest that we instead call CancelWithError with sentinel error ErrTooManySteps, so callers can use errors.Is to understand if this - maximum number of steps hit - was why the thread was canceled.
Check #589 for an implementation of the proposed solution.