Если 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.
Это только идентификатор в интерпретируемой среде.