Common Lisp allows exception handling through conditions and restarts. In rough terms, when a function throws an exception, the “catcher” can decide how/whether the “thrower” should proceed. Does Prolog offer a similar system? If not, could one be built on top of existing predicates for walking and examining the call stack?
Common Lisp allows exception handling through conditions and restarts . In rough terms, when
Share
The ISO/IEC standard of Prolog provides only a very rudimentary exception and error handling mechanism which is – more or less – comparable to what Java offers and far away from Common Lisp’s rich mechanism, but there are still some points worth noting. In particular, beside the actual signalling and handling mechanism, many systems provide a mechanism similar to
unwind-protect. That is, a way to ensure that a goal will be executed, even in the presence of otherwise unhandled signals.ISO throw/1, catch/3
An exception is raised/thrown with
throw(Term). First a copy ofTermis created withcopy_term/2lets call itTermcopyand then this new copy is used to search for a correspondingcatch(Goal, Pattern, Handler)whose second argument unifies withTermcopy. WhenHandleris executed, all unifications caused byGoalare undone. So there is no way for theHandlerto access the substitutions present whenthrow/1is executed. And there is no way to continue at the place where thethrow/1was executed.Errors of built-in predicates are signaled by executing
throw(error(Error_term, Imp_def))whereError_termcorresponds to one of ISO’s error classes andImp_defmay provide implementation defined extra information (like source file, line number etc).There are many cases where handling an error locally would be of great benefit but it is deemed by many implementors to be too complex to implement.
The additional effort to make a Prolog processor handle each and every error locally is quite considerable and is much larger than in Common Lisp or other programming languages. This is due to the very nature of unification in Prolog. The local handling of an error would require to undo unifications performed during the execution of the built-in: An implementor has thus two possibilities to implement this:
Similar complexities are caused by exploiting WAM registers within built-ins. Again, one has the choice between a slow system or one with significant implementation overhead.
exception_handler/3
Many systems, however, provide internally better mechanisms, but few offer them consistently to the programmer. IF/Prolog provides
exception_handler/3which has the same arguments ascatch/3but handles the error or exception locally:setup_call_cleanup/3
This built-in offered by quite a few systems. It is very similar to
unwind-protectbut requires some additional complexity due to Prolog’s backtracking mechanism. See its current definition.All these mechanisms need to be provided by the system implementor, they cannot be built on top of ISO Prolog.