4

I have this newbie question: in Standard ML, how can you catch an exception like "Error: unbound variable or constructor: foo"?

I tried to do this with the following program:

(foo())
handle Error msg => ();

But REPL complains: "Error: non-constructor applied to argument in pattern: Error"

Thanks in advance.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
Chao Sun
  • 655
  • 1
  • 6
  • 16

2 Answers2

3

First of all it's handle Error => ... (or handle error => ... or handle TheSpecificExceptionIWantToCatch => ...), not handle Error msg => .... You can only write handle Foo msg => ... if Foo is a constructor with one argument, which, as the error message suggests, Error is not.

Secondly "unbound variable" is a compilation error, not an exception, so it can't be caught.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
1

Just to add to the existing answer. I noticed Chao tried to "catch" an Error based on the message it received trying to execute the code. A genuine exception message in the REPL is reported right after the line val it = () : unit, indicating it happens after the interpretation phase. Furthermore, in the Standard ML of New Jersey v110.76 interpreter, it appears at execution time with a message like:

uncaught exception ExceptionName raised at: filename.sml:linei.columni-linej.columnj

So not seeing an explicit message along these lines should raise the alarm that no exception has been raised, no pun intended. Since the question was how to catch an exception not an error, I think the mechanism for an exception has to be briefly explained:

  1. Somewhere in the code, within the lexical scope of where it will be used, an exception binding has to be defined: exception MyException or exception MyException2 of String
  2. Somewhere in an expression a case is found that merits the interruption of normal control flow and thus uses the following primitive to do just that: raise MyException or raise (MyException2("Error in foo"))
  3. The exceptional interruption of flow can be caught with a handle expression that uses pattern matching on the exception constructor and submits and alternative expression for evaluation. In this case expression e1 raises the exception and the handler returns expression e2: e1 handle MyException => e2

For more details on how to write clean and elegant exception handlers for complex functions, with recovery of execution if so desired, read this page of the on-line notes Programming in Standard ML by Robert Harper

Pablo Adames
  • 578
  • 6
  • 12