I think this particular one is fairly straightforward:
1. It's a non-obvious solution (Lisp had (and in some cases, still has) other methods of doing what other languages do with exceptions before the current system
2. It was hard to implement in popular languages; any language without closures is unlikely to have this.
3. More dynamic languages that could implement these fairly easily inherited their exception system from less dynamic languages, with some other features tacked-on, or got the dynamic features after the exception system was already created.
4. Situations in which you aren't going to restart are already (mostly?) solved by the "shove the call-stack into the exception object" which significantly reduces pain compared to e.g. C++ exceptions.
1. It's a non-obvious solution (Lisp had (and in some cases, still has) other methods of doing what other languages do with exceptions before the current system
2. It was hard to implement in popular languages; any language without closures is unlikely to have this.
3. More dynamic languages that could implement these fairly easily inherited their exception system from less dynamic languages, with some other features tacked-on, or got the dynamic features after the exception system was already created.
4. Situations in which you aren't going to restart are already (mostly?) solved by the "shove the call-stack into the exception object" which significantly reduces pain compared to e.g. C++ exceptions.