Skip to content

Commit ef44661

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

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

rfcs/0190-forbid-with.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
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+
with pkgs; inherit (pkgs) git vim curl; [
58+
git
59+
vim
60+
curl
61+
]
62+
```
63+
64+
## Function arguments
65+
66+
```nix
67+
# Before
68+
{ pkgs, ... }:
69+
with pkgs; {
70+
buildInputs = [ git vim ];
71+
}
72+
73+
# After
74+
{ pkgs, ... }:
75+
let
76+
inherit (pkgs) git vim;
77+
in {
78+
buildInputs = [ git vim ];
79+
}
80+
```
81+
82+
## Nested scopes
83+
84+
```nix
85+
# Before
86+
with pkgs; {
87+
meta = with lib; {
88+
license = with licenses; [ mit ];
89+
};
90+
}
91+
92+
# After
93+
let
94+
inherit (pkgs.lib.licenses) mit;
95+
in {
96+
meta = {
97+
license = [ mit ];
98+
};
99+
}
100+
```
101+
102+
# Drawbacks
103+
[drawbacks]: #drawbacks
104+
105+
- **Increased verbosity**: Code may become slightly longer due to explicit prefixes or inherit statements
106+
- **Migration effort**: Existing codebase requires changes
107+
- **Learning curve**: Contributors familiar with `with` need to adapt to new patterns
108+
- **Backward incompatible**: requires changing Nix code used "in the wild"
109+
110+
However, these drawbacks are outweighed by the benefits of clearer, more maintainable code.
111+
112+
# Alternatives
113+
[alternatives]: #alternatives
114+
115+
Just discourage usage of `with`, but in this case most things still can not be statically checked.
116+
117+
# Unresolved questions
118+
[unresolved]: #unresolved-questions
119+
120+
# Future work
121+
[future]: #future-work

0 commit comments

Comments
 (0)