Skip to content

Commit b4711e6

Browse files
committed
first draft of "forbid with"
1 parent c655bda commit b4711e6

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

rfcs/0190-forbid-with.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
---
2+
feature: ban-with-expressions
3+
start-date: 2025-10-07
4+
author: 6543
5+
co-authors:
6+
shepherd-team:
7+
shepherd-leader:
8+
related-issues:
9+
- https://github.com/NixOS/rfcs/pull/120
10+
- https://github.com/NixOS/nixpkgs/pull/413393
11+
---
12+
13+
# Summary
14+
[summary]: #summary
15+
16+
Completely prohibit the usage of `with` expressions in nixpkgs to improve code clarity, maintainability, and enable better static analysis. Instead using explicit `inherit` statements should be used if bringing attributes into scope is desired.
17+
18+
# Motivation
19+
[motivation]: #motivation
20+
21+
The `with` expression in Nix creates several problems that impact code quality and tooling:
22+
23+
- **Unclear variable origins**: When reading code with `with`, it's unclear where variables come from without evaluating the expression
24+
- **Difficult static analysis**: Tools cannot determine variables without running full nix evaluation
25+
- **Debugging difficulties**: Error messages become less helpful when variable sources are ambiguous
26+
- **Code review challenges**: Reviewers can not simply relay on a diff view and must read the full code and not miss any scope
27+
28+
The `inherit` statement provides a better alternative that is:
29+
30+
- **Explicit**: Clearly shows which attributes are being brought into scope
31+
- **Traceable**: Easy to see where each variable comes from
32+
- **Analyzable**: Static analysis tools can easily understand the code structure
33+
- **Debuggable**: Error messages can point to specific inherit statements
34+
35+
# Detailed design
36+
[design]: #detailed-design
37+
38+
1. **Immediate prohibition**: New code in Nixpkgs must not use `with` expressions
39+
2. **Gradual migration**: Existing `with` expressions should be migrated to `inherit` over time
40+
3. **CI enforcement**: Add automated checks to prevent new `with` expressions from being merged
41+
4. **Documentation updates**: Update Nixpkgs contributor guidelines to reflect this policy
42+
43+
# Examples and Interactions
44+
[examples-and-interactions]: #examples-and-interactions
45+
46+
## Simple attribute access
47+
48+
```nix
49+
# Before
50+
with pkgs; [
51+
git
52+
vim
53+
curl
54+
]
55+
56+
# After
57+
let
58+
inherit (pkgs) git vim curl;
59+
in [
60+
git
61+
vim
62+
curl
63+
]
64+
```
65+
66+
## Function arguments
67+
68+
```nix
69+
# Before
70+
{ pkgs, ... }:
71+
with pkgs; {
72+
buildInputs = [ git vim ];
73+
}
74+
75+
# After
76+
{ pkgs, ... }:
77+
let
78+
inherit (pkgs) git vim;
79+
in {
80+
buildInputs = [ git vim ];
81+
}
82+
```
83+
84+
## Nested scopes
85+
86+
```nix
87+
# Before
88+
with pkgs; {
89+
meta = with lib; {
90+
license = with licenses; [ mit ];
91+
};
92+
}
93+
94+
# After
95+
let
96+
inherit (pkgs.lib.licenses) mit;
97+
in {
98+
meta = {
99+
license = [ mit ];
100+
};
101+
}
102+
```
103+
104+
# Drawbacks
105+
[drawbacks]: #drawbacks
106+
107+
- **Increased verbosity**: Code may become slightly longer due to explicit prefixes or inherit statements
108+
- **Migration effort**: Existing codebase requires changes
109+
- **Learning curve**: Contributors familiar with `with` need to adapt to new patterns
110+
- **Backward incompatible**: requires changing Nix code used "in the wild"
111+
112+
However, these drawbacks are outweighed by the benefits of clearer, more maintainable code.
113+
114+
# Alternatives
115+
[alternatives]: #alternatives
116+
117+
Just discourage usage of `with`, but in this case most things still can not be statically checked.
118+
119+
# Unresolved questions
120+
[unresolved]: #unresolved-questions
121+
122+
# Future work
123+
[future]: #future-work

0 commit comments

Comments
 (0)