DefineExpr

From Erights

(Difference between revisions)
Jump to: navigation, search
(add tests, rename fields (MarkM agrees))
(Scope)
Line 15: Line 15:
[[Node scope rules|seq]](<var>pattern</var>, <var>optExitExpr</var>, <var>specimen</var>)
[[Node scope rules|seq]](<var>pattern</var>, <var>optExitExpr</var>, <var>specimen</var>)
-
Note that this order differs from the evaluation order; the static constraints prevent this from being impossible without [[promise]]s.
+
Note that this order differs from the evaluation order; the static constraints make this possible without [[promise]]s.
== Evaluation ==
== Evaluation ==

Revision as of 05:57, 4 January 2009

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

  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
# value: 3.14159

? pi
# value: 3.14159
? def var x := 1
> x
# value: 1

? x := 2
> x
# value: 2

With optEjectorExpr 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 optEjectorExpr 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

Personal tools
more tools