SML# Document Version 4.0.0
19 Expressions

19.24 Dynamic type cast expression _dynamic exp as ty

This expression performs dynamic type cast of dynamically-typed value exp to ty. The type of exp must be τ Dynamic.dyn for some τ. The type of this expression is ty.

To evaluate this expression, exp is evaluated and the dynamically-typed value v is obtained. The value of this expression depends on the structure of v and ty. The rule of dynamic type cast is the following:

  • When ty is Dynamic.void Dynamic.dyn, the value of this expression is v.

  • When ty is τ Dynamic.dyn for some tau, if v has a view of τ (a substructure of v can be extracted as a value of τ), the value of this expression is v. Otherwise, the Dynamic.RuntimeTypeError excepstion is raised.

  • When ty does not include Dynamic.dyn, the type of v is identical to ty, the value of this expression is the value obtained by type-casting v to ty. Otherwise, the Dynamic.RuntimeTypeError excepstion is raised.

  • When ty includes Dynamic.dyn as its substructure, the above rules are applied recursively on the structure of v and ty.

For example, suppose the following list of records:

val r = Dynamic.dynamic [{name = "Joe", age = 21}, {name = "Sue", age = 31}];

The following casts are correct:

_dynamic r as {name:string, age:int} list;
_dynamic r as {name:Dynamic.void Dynamic.dyn, age:int} list;
_dynamic r as Dynamic.void Dynamic.dyn;
_dynamic r as Dynamic.void Dynamic.dyn list;
_dynamic r as {name:string, age:int} Dynamic.dyn list;
_dynamic r as {name:string} Dynamic.dyn list;
_dynamic r as {name:string, age:int} list Dynamic.dyn;
_dynamic r as {age:int} list Dynamic.dyn;

Note that v is not always a data structure that is typable in ML. For example, suppose the following heterogeneous list:

val l = Dynamic.fromJson
          "[{\"name\":\"Joe\", \"age\":21},\
          \{\"name\":\"Sue\", \"grade\":2.0},\
          \{\"name\":\"Robert\", \"nickname\":\"Bob\"}]";

The following casts are correct:

_dynamic l as Dynamic.void Dynamic.dyn;
_dynamic l as Dynamic.void Dynamic.dyn list;
_dynamic l as {name:string} Dynamic.dyn list;
_dynamic l as {name:string} list Dynamic.dyn;
_dynamic l as {name:Dynamic.void Dynamic.dyn} Dynamic.dyn list;

To use this expression in the separate compilation mode, "reify.smi" must be _required.