Jedi Environment Diagrams: More Sample Problems

Assume the following declarations have been made in Jedi:

-> def x = 10
ok
-> def y = 20
ok
-> def z = 30
ok

(Since these declarations are made at the Jedi prompt, the bindings they create will be stored in the global environment.)

In the following examples, draw and environment diagram and supply the result of executing the following Jedi expressions.

Example 1

-> def foo = {def x = 2 * y; def y = x + 5; lambda(a, b) a + b + x + y + z}
ok
-> foo(x, y)
?

The answer is ? = 145. Here's the diagram: diagram1.jpg. It's tricky (and I like it) because Block.execute uses sequential execution to execute its local expressions. This means later declarations in the block can refer to earlier ones, but not vice-versa.

Note: There are three types of blocks in language design:

·       Sequential: Expressions in the block are executed sequentially, so declarations early in the sequence don't know about later declarations.

·       Collateral: Expressions are executed in "parallel", so declarations late in the sequence don't know about earlier declarations.

·       Recursive: Declarations early in the sequence do know about later declarations. This allows for recursive forward referencing.

Example 2

Here's the reverse problem, a block inside of a lambda:

-> def foo = lambda(a, b) { def x = 2 * y; def y = a + b; a + b + x + y + z }
ok
-> foo(x/2, z)
?

Result = 140. Here's the diagram.

Example 3

-> def meta = lambda(f) f(x + 2)
ok
-> def square = lambda(x) x * x
ok
-> meta(square)
?

Should be 144

Example 4

-> def meta = lambda(f) lambda(x) f(x)
ok
-> def bar = meta(lambda(y) y * y)
ok
-> bar(10)
?

The answer is ? = 100. Here's the diagram: diagram2.jpg. This is kind of a nasty one, but should really test your knowledge. Meta is a true combinator. It takes a function, f, as inlut, and returns a function, lambda(x) f(x), as output. Bar is the output of meta, when f = lambda(y) y * y. In other words, bar(10) = 10 * 10 = 100. Note, that the defining environment of f is the global environment, GE, because this was the current environment when lambda(y) y * y was excuted.