DefineExpr
From Erights
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.
Contents |
Fields
Scope
seq(pattern, optExitExpr, specimen)
Note that this order differs from the evaluation order; the static constraints make this possible without promises.
Evaluation
- If present, optExitExpr is evaluated.
- specimen is evaluated.
- 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 # value: 3.14159 ? pi # value: 3.14159
? def var x := 1 > x # value: 1 ? x := 2 > x # value: 2
With optExitExpr specified, but making no difference:
? def x :int exit throw := 9 # value: 9 ? x # value: 9 ? def x :String exit throw := 9 # problem: the int 9 doesn't coerce to a String
With optExitExpr different:
? def x :int exit def _(e) :void { print(e); throw("biff") } := 9 # value: 9
? def x :String exit def _(e) :void { print(e); throw("biff") } := 9 # stdout: problem: the int 9 doesn't coerce to a String # problem: biff
Demonstration of the evaluation order:
? def via (fn s,_ {println("patt"); throw("exit")}) x \ > exit (println("ejector"); null) \ > := (println("specimen"); 8) # stdout: ejector # specimen # patt # # problem: exit
A bogus exit, which does not return when it should (this is throw.eject behavior):
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 # problem: optEjector <__main$_> returned: null
Scope tests:
? {def y := 0; {def ==0 exit (def y := null) := y}} # problem: null is not 0
XXX write more scope tests