All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.pkl.thirdparty.paguro.function.LazyRef Maven / Gradle / Ivy

Go to download

Fat Jar containing pkl-cli, pkl-codegen-java, pkl-codegen-kotlin, pkl-config-java, pkl-core, pkl-doc, and their shaded third-party dependencies.

There is a newer version: 0.27.1
Show newest version
package org.pkl.thirdparty.paguro.function;

// Should this bee an inner class of Fn0?

import org.pkl.thirdparty.jetbrains.annotations.NotNull;
import org.pkl.thirdparty.jetbrains.annotations.Nullable;

/**
 Lazily initialize a value (and free the initialization resources) on the first call to get().
 Subsequent calls to get() cheaply return the previously initialized value.  This class is thread-safe if the producer
 function and the value it produces are free from side effects.
 */
public class LazyRef implements Fn0 {
    private @Nullable Fn0 producer;
    private T value;

    private LazyRef(Fn0 p) { producer = p; }

    /**
     Construct a LazyRef from the given initialization function.

     @param producer a zero-argument function that produces the desired value when called.

     @return a LazyRef with the given producer.
     */
    public static  @NotNull LazyRef of(@NotNull Fn0 producer) {
        return new LazyRef<>(producer);
    }

    /**
     The first call to this method calls the initialization function, caches the result, and hands
     the initialization function reference to the garbage collector so that initialization resources
     can be freed.  Subsequent calls return the precomputed value.

     @return the same value every time it is called.
     */
    // This whole method is synchronized on the advice of Goetz2006 p. 347
    public synchronized T applyEx() {
        // Have we produced our value yet?
        if (producer != null) {
            // produce our value.
            value = producer.apply();
            // Delete the producer to 1. mark the work done and 2. free resources.
            producer = null;
        }
        // We're clear to return the lazily computed value.
        return value;
    }

    // I don't like this because it's not referentially transparent.
//        public boolean isRealizedYet() { return producer == null; }

    // I don't like this because it's not referentially transparent, but it could be helpful for testing.
    /**
     Useful for debugging, but not referentially transparent (sometimes returns LazyRef(*not-computed-yet*),
     sometimes shows the value that was computed).
     @return a string describing this LazyRef and showing whether or not its value has been computed yet.
     */
    public @NotNull String toString() { return "LazyRef(" + ((producer == null) ? value : "*not-computed-yet*") + ")"; }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy