--- /dev/null
+package org.simantics.scl.runtime.lazy;
+
+import org.simantics.scl.runtime.function.Function;
+import org.simantics.scl.runtime.function.FunctionImpl1;
+import org.simantics.scl.runtime.tuple.Tuple0;
+
+public class Lazy {
+ private static final Function CYCLIC_EVALUATION_TRAP = new FunctionImpl1() {
+ @Override
+ public Object apply(Object p0) {
+ throw new RuntimeException("Cyclic dependency on lazy value.");
+ }
+ };
+
+ volatile Function thunk;
+ volatile Object value;
+
+ public Lazy(Function thunk) {
+ this.thunk = thunk;
+ }
+
+ public Object force() {
+ if(thunk == null)
+ return value;
+ else {
+ synchronized(this) {
+ Function curThunk = thunk;
+ if(curThunk != null) {
+ thunk = CYCLIC_EVALUATION_TRAP;
+ value = curThunk.apply(Tuple0.INSTANCE);
+ thunk = null;
+ }
+ }
+ return value;
+ }
+ }
+}