Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do Nix lambdas and the ? operator interact like so?

Tags:

nix

nixos

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?

like image 731
AMemberofDollars Avatar asked Sep 01 '25 21:09

AMemberofDollars


1 Answers

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
like image 174
David Grayson Avatar answered Sep 03 '25 17:09

David Grayson