Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> I find `with myAttrs; myExpr`

To make it clearer, he is saying that he does

with { foo = "bar"; }; <some other block>

instead of

let foo = "bar"; in <some other block>

The differences here so other people can follow along.

1. with will not shadow variables defined higher up. This can be either desirable or very confusing.

2. let is recursive by default, meaning you can reference other variables in that block. This behavior can be mimicked with `with rec {}`



Yep. The advantage of `with` is that we're dealing with first-class values (attribute sets, like `{ foo = "bar"; }`), rather than an implicit environment/context. My rationale is at https://github.com/NixOS/nix/issues/1361#issuecomment-390420...

The thing about shadowing is that `with` will not shadow anything that's in the implicit context, which includes things defined by `let` (hence why I avoid it) and function arguments (unavoidable). We can shadow other `with` bindings as much as we like, e.g.

    with { foo = 1; };
    with { foo = 2; };
    with { foo = 3; };
    with { bar = with { foo = 4; }; foo; };
    [ foo bar ]
This evaluates to [ 3 4 ], since later bindings to `foo` will shadow/override earlier ones.

This doesn't work for bindings that are in the implicit environment/context, for example:

    with {
      f = foo: with { foo = 42; }; foo;
    };
    f 123
This evaluates to 123, since the binding `with { foo = 42; }; ...` doesn't shadow/override the argument `foo`.

The rationale for this behaviour is to avoid changes made to an attrset from overriding explicit arguments. For example:

    foo:
      with bar;
      x + foo
This is presumably meant to behave like `foo: bar.x + foo`, but a future change to `bar` might include a `bar.foo` attribute, in which case we don't want the above to change behaviour to `foo: bar.x + bar.foo`.

I understand this rationale, especially when using huge, constantly-changing attrsets like `with nixpkgs; ...`, but it's still annoying ;)




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: