It’s WIP, but maybe useful.
How does it compare to https://noogle.dev/ ? I am still looking for a search which also knows about the more obscure builtins, like the unsafe ones
I would recommend against using
builtins directly. Instead use the Nixpkgs
lib, which contains (or should contain) all the builtins, and sometimes improved versions, such as
foldl', as well as “polyfills” or fallback implementations that make new builtins available on the whole range of Nix versions that Nixpkgs supports.
The builtins are hugely affected by the requirement of reproducibility. The Nix language, including its builtins is meant to be a source of stability, and we’ve been rather successful at keeping it stable. You can still evaluate decade old expressions and get the same result. This would not be the case if we changed the builtins whenever we felt like it.
lib doesn’t suffer from this requirement. It can evolve, and old expressions keep working because they simply use an older
And finally there’s the argument of consistency. You probably want to use
lib because of some functions anyway, and it’s nicer if you don’t have to think whether some function comes from
I actually did not know about noogle.dev. I find this great too! This builtins search was a fast POC copy of the home manager options search. If people use it, I might continue adding features and searchable content.
Could we develop an elegant solution to get rid of those numerous
As I remember, there have been steps towards it years ago, i.e.
import was able to pass a hidden parameter to every call, akin to Scala’s
implicit so a variable from the importing scope magically appears in the importing scope (it has not to be necessarily
lib.* are the first candidate for that), then the feature has been abandoned or even reverted.
builtins. (but not
lib.) is the same as
__, e.g. one can write
__toJSON instead of
builtins.toJSON, this seems so ugly so almost everybody prefers
This advice may be true for contributing to nixpkgs, but there is also a world outside. Some people may like to use builtins directly without introducing an additional dependency on nixpkgs.
Having this layer of abstraction is currently also not really practical because some builtins are not proxied through. But I understand and support your vision, to decouple things.
I recommend the same for projects other than Nixpkgs.
You can get a suitably small dependency from nix-community/nixpkgs.lib, or hopefully natively from the actual source in a couple of months, after improvements to
fetchTree and the git fetcher.
I’ll be happy to review the addition of whatever is still missing from
You can use the
with lib; construct. But I guess you meant something else?
with lib often have naming conflicts with local variables (and the conflict resolution order is not intuitive at all), so, yes, it’s better to invent something else. But I don’t have any good ideas yet, so far I write explicitly
Same. Also I read the
with construct is considered an anti pattern now. So there’s that too.
I’m pretty happy doing something along the lines of:
let inherit (builtins) readFile fromTOML; inherit (lib.lists) forEach foldl flatten remove; inherit (lib.attrsets) recursiveUpdate optionalAttrs mapAttrsToList; qw = s: lib.strings.splitString " " s; # ... in
but I will keep in mind the advice about referring to
I never thought of combining inherit with let in. It looks nice.
I would recommend against using
builtinsdirectly. Instead use the Nixpkgs
I would do this if there was a separate repo for lib, and if the lib didn’t include stdenv (e.g. if it was a pure).
I know I know “it’s a lazy runtime” and all, but I really dislike adding a dependency on a massive repo/tarball just to use a single tiny little helper function.
It’s an anti-pattern because
with lib is awful for the new-to-nix dev, and the performance of the nix runtime. Especially because doing with lib at the top makes it really likely for nested
with’s, and it’s literally impossible to do static code analysis on nested withs (for humans or editor tooling). We have to run the code to even know where the var comes from.
A new dev seeing
builtin.map on Github knows exactly what to Google when they don’t understand the arguments.
But seeing a
map inside of a
with lib; with pkgs; with thisPkgUtils;, becomes a massive undertaking to know which attrSet it came from, find its implementation, or even just know what-to-search to figure out what the arguments mean.
I had the same conclusion about discoverability. It’s the same deal in Haskell. But I had never thought about performance penalty, although it makes sense too.
with statement. According to MDN it “makes optimization impossible” among other issues, and AFAIK out of all the bad behavior in JS it’s the only keyword that’s ever been removed.
GitHub - nix-community/nixpkgs.lib: nixpkgs lib for cheap instantiation [maintainer=@github-action] (with initial help from @blaggacao) might be relevant to your interests.
lib maintainer I’d be totally on-board to have a separate repo for it!
This is awesome thank you! I will definitely use this. Even if its not all the way pure its a big upgrade.
this is going a bit offtopic but what is currently stoping us?