|
require 'continuation'
|
|
|
|
# The idea of the code is to run '[0].map &f'
|
|
# with '&f' stopping the execution of 'map'
|
|
# (by aborting the computation (calling k0))
|
|
# and storing the continuation in 'x' (to
|
|
# resume it later). Calling 'x' with a value
|
|
# 'y' should resume the continuation with the
|
|
# value 'y' which will send it the the map
|
|
# ('[0].map { |x| y } and thus returning [y].
|
|
# This is the idea of making a Zipper.
|
|
|
|
x = callcc { |k0|
|
|
r0 = [0].map { |x| callcc { |k1|
|
|
r1 = (lambda { |y| callcc { |k2|
|
|
@savecont = k2
|
|
k1.call y
|
|
}
|
|
}
|
|
)
|
|
k0.call r1
|
|
}
|
|
}
|
|
@savecont.call r0
|
|
}
|
|
|
|
puts "=> x"
|
|
print " x = ", x.to_s, "\n"
|
|
puts ""
|
|
|
|
# x = lambda { |x| callcc { |k2|
|
|
# @@mcs = k2
|
|
# k1.call x
|
|
# }
|
|
# }
|
|
|
|
|
|
|
|
# We call 'x' three times with values 1, 2 and 3
|
|
# The resulting values should be respectively
|
|
# [1], [2] and [3] but it is not.
|
|
|
|
x1 = x.call 1
|
|
|
|
puts "=> x1 = x.call 1"
|
|
print " x1 = ", x1.to_s, "\n"
|
|
puts ""
|
|
print " x = ", x.to_s, "\n"
|
|
puts ""
|
|
|
|
# x1 = callcc { |k2|
|
|
# @savecont = k2
|
|
# k1.call 1
|
|
# }
|
|
#
|
|
# = { r = [0].map { |x| 1 }
|
|
# @savecont.call r
|
|
# }
|
|
# = k2 [1]
|
|
# = [1]
|
|
|
|
# Indeed when '1' is sent to 'x', the 'map'
|
|
# receive the value '1' and finishes. All is
|
|
# as expected. 'x1' the array [1]
|
|
# 'x' is still the same procedure.
|
|
|
|
|
|
# Now doing the same with '2' instead of '1'
|
|
# We should get [2] but we get [1,2] and 'x1'
|
|
# changed.
|
|
|
|
|
|
x2 = x.call 2
|
|
# 'x2' should be [2]
|
|
|
|
puts "=> x2 = x.call 2"
|
|
print " x2 = ", x2.to_s, "\n"
|
|
puts ""
|
|
print " x = ", x.to_s, "\n"
|
|
print " x1 = ", x1.to_s, "\n"
|
|
puts ""
|
|
|
|
# 'x' being the same procedure, calling 'x' with
|
|
# '2' should proceed exactly like 'x1' sending '2'
|
|
# instead of '1' to the map ('[0].map { |x| 2 }')
|
|
# and returning [2] but it returns [1,2].
|
|
# Furthermore 'x1' which should be unchanged, is
|
|
# now [1,2] too. Very strange behavior.
|
|
|
|
|
|
|
|
# Once again:
|
|
|
|
x3 = x.call 3
|
|
# 'x3' should be '[3]'
|
|
|
|
puts "=> x3 = x.call 3"
|
|
print " x3 = ", x3.to_s, "\n"
|
|
puts ""
|
|
print " x = ", x.to_s, "\n"
|
|
print " x1 = ", x1.to_s, "\n"
|
|
print " x2 = ", x2.to_s, "\n"
|
|
puts ""
|