While trying out nix & nix repl:
Welcome to Nix version 2.3.6. Type :? for help.
nix-repl> pkgs = import <nixpkgs> {}
nix-repl> builtins.typeOf pkgs
"set"
nix-repl> pkgs ? "firefox"
true
nix-repl> func = (n: pkgs ? "firefox")
nix-repl> func null
true
nix-repl> func = (n: pkgs ? n)
nix-repl> func "firefox"
false
I assumed that func "firefox"
would return true
.
What Nix paradigms or concepts explain why func "firefox"
returns false
in this example?
The thing you write after ?
is not an expression: it is an attribute path. This allows you to do powerful things like pkgs ? hello.src
which probes to see whether pkgs
has an attribute named hello
which has an attribute named src
.
When Nix evaluates a ? b
, Nix just looks at the name "b", it does not consider whether "b" is a variable in the local context. So pkgs ? n
is true if an only if pkgs
is a set with a member that literally is named "n".
Here is an example repl session that explores the issue. The last line shows a possible solution for what I think you are trying to do.
nix-repl> pkgs = import <nixpkgs> {}
nix-repl> pkgs ? "firefox"
true
nix-repl> pkgs ? "name"
false
nix-repl> name = "firefox"
nix-repl> pkgs ? name
false
nix-repl> firefox = "name"
nix-repl> pkgs ? firefox
true
nix-repl> pkgs ? "${name}"
true
nix-repl> builtins.hasAttr name pkgs
true