DefineExpr

DefineExpr is a Kernel-E node which matches a pattern against a specified value.

"def" pattern ("exit" optExitExpr )? ":=" specimen

Note that the syntax is identical to DefrecExpr, the nonkernel expression which allows recursive definitions; DefineExpr rejects such uses.

Fields

 * pattern :Pattern
 * optExitExpr :nullOk [ EExpr]
 * specimen :EExpr

Scope
seq( pattern, optExitExpr , specimen )

Note that this order differs from the evaluation order; the static constraints make this possible without promises.

Evaluation

 * 1) If present, optExitExpr is evaluated.
 * 2) specimen is evaluated.
 * 3) pattern is matched against the result of specimen, with the result of optExitExpr , or throw if not present, as the ejector.

Static constraints

 * specimen may not use nouns bound by pattern . (See DefrecExpr.)
 * optExitExpr may not use nouns bound by pattern.
 * pattern may not use nouns bound by specimen.
 * pattern may not use nouns bound by optExitExpr.

Examples
Simple uses with FinalPattern, VarPattern and LiteralExpr:

? def pi := 3.14159 ? pi
 * 1) value: 3.14159
 * 1) value: 3.14159

? def var x := 1 > x ? x := 2 > x
 * 1) value: 1
 * 1) value: 2

With optExitExpr specified, but making no difference:

? def x :int exit throw := 9 ? x ? def x :String exit throw := 9 With optExitExpr different:
 * 1) value: 9
 * 1) value: 9
 * 1) problem: the int 9 doesn't coerce to a String

? def x :int exit def _(e) :void { print(e); throw("biff") } := 9
 * 1) value: 9

? def x :String exit def _(e) :void { print(e); throw("biff") } := 9 Demonstration of the evaluation order:
 * 1) stdout: problem: the int 9 doesn't coerce to a String
 * 1) problem: biff

? def via (fn s,_ {println("patt"); throw("exit")}) x \ >  exit (println("ejector"); null) \ >  := (println("specimen"); 8) A bogus exit, which does not return when it should (this is throw.eject behavior):
 * 1) stdout: ejector
 * 2)         specimen
 * 3)         patt
 * 1) problem: exit

XXX in E-on-Java this creates a note in the trace that the ejector returned and proceeds as if the ejector was null; the shown behavior is from E-on-CL; which to pick?

? def x :String exit def _(_) :void {} := 9 Scope tests:
 * 1) problem: optEjector <__main$_> returned: null

? {def y := 0; {def ==0 exit (def y := null) := y}}
 * 1) problem: null is not 0

XXX write more scope tests