> [...] the algorithms I am aware of for finding shortest paths require mutable vertices that store the scores and pointers (edges) for the best part found so far.
No problem. Traditional loops with mutable variables translate straight-forward to tail recursive calls, if you want to write your algorithm like that.
Though actually my argument was less about not mutating your functions internal variables---but about interacting with the world outside your function via a well defined interface. (In this case, via arguments and returned values.)
The most 'mainstream' language that encourages such a strong adherence to declared interfaces is Haskell. But the imperative D can do something similar:
"In a slightly less precise way, this means that pure functions always have the same effect and/or return the same result for a given set of arguments. As a consequence, a pure function for example cannot call other impure functions, or perform any kind of I/O (in the classical sense)."
http://klickverbot.at/blog/2012/05/purity-in-d/