#156 Dependency on files list not correctly recorded

open
nobody
None
5
2009-05-04
2009-05-04
Anonymous
No

It appears that there's a situation where a dependency on the existence of a variable isn't properly recorded. I've created a test case.

Discussion

  • Nobody/Anonymous

     
  • Nobody/Anonymous

    Crap, I was only able to add one file necessary for the bug. Whatever, they're small and I'll just add them as text:

    foo.ves:

    import bar = bar.ves;

    {
    return bar()/test();
    }

    bar.ves:

    files
    foo;

    {
    test(t: text)(): binding
    {
    a = [t, foo, bar];
    return a;
    };

    return [test = test("hello")];
    }

    foo : "hello world"
    bar : "hello world"

    Step 1. Create the files above into an open vesta work directory
    Step 2:
    $ vmake foo.ves
    Unbound variable `bar' encountered during evaluation in context:
    [ ].
    0/Error: Vesta evaluation failure; exiting.
    2 errors were reported.
    Vesta evaluation failed.

    Step 3. Now fix the typo in bar.ves by adding the file 'bar' to the files list, i.e.:
    bar.ves:

    files
    foo;
    bar;

    {
    test(t: text)(): binding
    {
    a = [t, foo, bar];
    return a;
    };

    return [test = test("hello")];
    }

    Step 4. Now rerun the vmake command:
    Advancing to /vesta/desres.deshaw.com/play/batsonb/vutilities/checkout/81.batsonb_deshaw.com.2/16
    /vesta/desres.deshaw.com/play/batsonb/vutilities/checkout/81.batsonb_deshaw.com.2/10/bar.ves, line 9, char 20:
    0/Error:
    Unbound variable `bar' encountered during evaluation in context:
    [ ].
    0/Error: Vesta evaluation failure; exiting.

    2 errors were reported.
    Vesta evaluation failed.

    Note that the version we advanced to is not the same as the version of bar.ves--and it refused to pick up the changes to the files import line.

     
  • Kenneth C. Schalk

    I've verified the problem. It's not specific to the files
    clause; the variables in question can come from any kind of
    assignment.

    The false cache hit is on the 'test("hello")' call which
    sets the value of t and returns another function. That
    cache entry records a dependency on the variable "foo",
    which is clearly taken from the definition context. However
    it does not record a dependency on the variable "bar" being
    un-defined. On a subsequent call where "foo" has the same
    values and "bar" is defined, the evaluator gets a cache hit
    on the function result which came from a definition context
    where "bar" was not set.

    Currently, missing variables are only detected during
    function execution. Only when the function is called does
    the evaluator determine that "bar" is not set. I believe
    that in order to avoid this kind of false cache hit the
    evaluator will need to check for missing variables sooner
    (i.e. variables used in the body of a user-defined function
    that are neither arguments to the function nor exist in its
    definition context). We could turn that information into a
    dependency on a cache entry such as the one this case is
    getting a false cache hit on, or we could simply give an
    error much sooner (at function definition).

    Incidentally, I think it would be preferable if we prevented
    the outer levels of a multi-argument-list self-currying
    function like this from being cached (i.e. made them
    implicitly /**nocache**/). They're clearly always a very
    small amount of work, since they don't even have any
    expressions to evaluate and merely bind variables for a
    later function call.

     

Log in to post a comment.