New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a --trace option for --eval to reproduce the "relevant expression context" #183

Closed
jwiegley opened this Issue Apr 19, 2018 · 9 comments

Comments

Projects
None yet
4 participants
@jwiegley
Copy link
Member

jwiegley commented Apr 19, 2018

If, during evaluation, we record the expression trees involved, and "color" them as we go, then at the point of reaching throwError we could dump the minimal expression tree relevant to the error:

  • Delete unreferenced set members
  • Delete unreferenced function arguments (if taking a parameter set)
  • Delete unused default arguments
  • Replace unevaluated thunks with nulls

This would make it easier to turn errors into test cases.

@jwiegley

This comment has been minimized.

Copy link
Member

jwiegley commented Apr 19, 2018

This is actually done now! I'm going to have to write a blog post tonight on how powerful recursion schemes can be. I was able to add this functionality without changing a single line in the original data types or evaluators.

@jwiegley jwiegley closed this Apr 19, 2018

@jwiegley

This comment has been minimized.

Copy link
Member

jwiegley commented Apr 19, 2018

@ryantrinkle The option is --trace, which for the given input file:

let x = { z = import ./eighty.nix + 20; w = 123; };
    y = "Hello";
    z = "Goodbye";
in assert 1 == 1; if x.z == 100 then y else 3

Produces this output:

Expression tree before winnowing:
--------
let
  x = {
    z = import ./eighty.nix + 20;
    w = 123;
  };
  y = "Hello";
  z = "Goodbye";
in assert 1 == 1;
if x.z == 100 then y else 3
--------
Expression tree after winnowing:
--------
let
  x = {
    z = 80 + 20;
    w = null;
  };
  y = "Hello";
in y
--------
"Hello"

This is actually working well enough that it produces a file which reproduces the <<loop>> I'm encountering in nixpkgs right now, in less than 10k lines. It still contains imports when those imports are the result of evaluation (i.e., the tracer can't see the import directly).

@jwiegley

This comment has been minimized.

Copy link
Member

jwiegley commented Apr 19, 2018

I need to use an evaluator here that does "no effect reduction", to further simplify the resulting expression tree and discover more importing opportunities. Right now the following fails to trigger a static load:

let callLibs = file: import file { lib = self; };
    trivial = callLibs ./trivial.nix;
in trivial

Also, we should be able to reduce all statically computable subexpressions. This will mean flagging builtins to know which cause external effects and which are pure.

@jwiegley jwiegley reopened this Apr 19, 2018

@jwiegley jwiegley self-assigned this Apr 19, 2018

@jwiegley jwiegley changed the title Add a debug option to reproduce the "relevant expression context" Add a --trace option for --eval to reproduce the "relevant expression context" Apr 19, 2018

@ryantrinkle

This comment has been minimized.

Copy link
Member

ryantrinkle commented Apr 19, 2018

This is insanely awesome. Both the functionality and the fact that it was so clean to add.

@domenkozar

This comment has been minimized.

Copy link
Collaborator

domenkozar commented Apr 19, 2018

👍 👍 👍

@gilligan

This comment has been minimized.

Copy link

gilligan commented Apr 19, 2018

😻

@jwiegley

This comment has been minimized.

Copy link
Member

jwiegley commented Apr 19, 2018

The code for this approach is here: https://github.com/jwiegley/hnix/blob/master/src/Nix/Trace.hs. Note that the only function doing real work is pruneTree, which decides what it means when an expression node has unreferenced parts. This code is called from here: https://github.com/jwiegley/hnix/blob/master/src/Nix/Entry.hs#L74

@jwiegley

This comment has been minimized.

Copy link
Member

jwiegley commented Apr 20, 2018

Blog article describing this process is up: http://newartisans.com/2018/04/win-for-recursion-schemes/

@jwiegley

This comment has been minimized.

Copy link
Member

jwiegley commented Apr 20, 2018

The pure reduction evaluator is now working and is part of --trace. See Reduce.hs for more details.

@jwiegley jwiegley closed this Apr 20, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment