如果a 是一个未声明的绑定,SML 将不会编译这样的程序:
- fun minus (x, y) = x-y;
> val minus = fn : int * int -> int
- minus (1, a);
! Toplevel input:
! minus (1, a);
! ^
! Unbound value identifier: a
这是一个编译错误,而不是运行时异常。由于缺少值绑定而导致运行时异常是您可以在动态类型语言中实现的,例如Python。正如 molbdnilo 所说,您必须在 SML 中实现解释器才能实现这样的动态行为。例如:
datatype expr = Add of expr * expr
| Sub of expr * expr
| Int of int
| Var of string
exception UnknownVar of string
fun lookup s [] = raise UnknownVar s
| lookup s ((t,x)::vtable) = if s = t then x else lookup s vtable
fun eval vtable (Add (e1, e2)) = eval vtable e1 + eval vtable e2
| eval vtable (Sub (e1, e2)) = eval vtable e1 - eval vtable e2
| eval vtable (Int x) = x
| eval vtable (Var s) = lookup s vtable
首先运行此解释器以产生有效结果,然后产生错误:
- eval [("foo",3),("bar",2)] (Sub (Var "foo", Var "bar"));
> val it = 1 : int
- eval [("foo",3)] (Sub (Var "foo", Var "bar"));
! Uncaught exception:
! UnknownVar "bar"
这是一个运行时异常,因为缺少变量。
这里"bar"是一个字符串而不是一个SML标识符。
它只是解释环境中的一个标识符。