Skip to content

Commit

Permalink
language: Explain that with does not shadow
Browse files Browse the repository at this point in the history
Until now, both `with` and `inherit` used the wording
"adds variables to the scope".

But that adding happens in very different ways:
`inherit` shadows, `with` does not.

This is confusing, compare:

    let
      a = "outer";
      attrs = { a = "inner"; b = 3; };
    in
      (with attrs; rec { res = [a b]; }).res

Result: `[ "outer" 3 ]`

    let
      a = "outer";
      attrs = { a = "inner"; b = 3; };
    in
      (rec { inherit (attrs) a b; res = [a b]; }).res

Result: `[ "inner" 3 ]`

This causes common packaging errors, such as:

    myOverlay = {
      
      zxing-cpp = callPackage ...; # the C++ package

      myPythonWithPackages = python.withPackages (ps: with ps; [
        numpy
        ...
        zxing-cpp  # Wrong:
                   # Incorrectly refers to the C++ package, not `ps.zxing-cpp`!
                   # Thus `import zxingcpp` fails at runtime.

Thus, the explicit warning.
  • Loading branch information
nh2 committed Apr 29, 2024
1 parent 2f67833 commit 899f61c
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion doc/manual/src/language/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,19 @@ This is an incomplete overview of language features, by example.
</td>
<td>

Add all attributes from the given set to the scope (evaluates to `1`)
Add all attributes from the given set to the scope (evaluates to `1`).

**Warning:**
In contrast to `inherit`, does not shadow existing variables with the same name!
Existing outer variables get precedence over variables coming from `with`. Example:
```
let
a = "outer";
attrs = { a = "inner"; b = 3; };
in
with attrs; [ a b ]
```
Evaluates to `[ "outer" 3 ]`.

</td>
</tr>
Expand All @@ -447,6 +459,7 @@ This is an incomplete overview of language features, by example.
<td>

Adds the variables to the current scope (attribute set or `let` binding).
Shadows existing variables with the same name.
Desugars to `pkgs = pkgs; src = src;`

</td>
Expand All @@ -460,6 +473,7 @@ This is an incomplete overview of language features, by example.
<td>

Adds the attributes, from the attribute set in parentheses, to the current scope (attribute set or `let` binding).
Shadows existing variables with the same name.
Desugars to `lib = pkgs.lib; stdenv = pkgs.stdenv;`

</td>
Expand Down

0 comments on commit 899f61c

Please sign in to comment.