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; } } }