The main difference is the time machine provided by retry, which backtracks to the start of a goal before re-running it. If the program has no interfering side effects this means you are really back at the old state. This has two enormous advantages. While walking around in languages without such a time machine you have to be very careful not to jump over the buggy function because if you did, you often have to restart from the beginning. When it is no problem to skip over the buggy code, one can use hierarchical debugging: first step over the whole goal. If you do not like the result, retry and step over each of the sub goals until you find one that misbehaves, etc.