Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Nix: String and Path Concatenation #nix #nixos

Nix String and Path Concatenation

From Bas van Dijk:

To understand these things I would recommend using nix-repl:

$ nix-repl
Welcome to Nix version 1.11.2. Type :? for help.

nix-repl> name = "bar"

nix-repl> ./foo + "${name}"
/home/bas.van.dijk/foobar

Note that the previous is equivalent to the simpler:

nix-repl> ./foo + name
/home/bas.van.dijk/foobar

The reason that you get "foobar" is that we didn't include a "/". So lets try to do that:

nix-repl> ./foo/ + name
error: syntax error, unexpected '+', at (string):1:8

Apparently the Nix path parser doesn't like a slash at the end of a path literal. So lets try adding the slash dynamically:

nix-repl> ./foo + "/" + name
/home/bas.van.dijk/foobar

What happened here? Well, + is left associative so it is interpreted as:

(./foo + "/") + name

Lets try evaluating that left expression alone:

nix-repl> ./foo + "/"
/home/bas.van.dijk/foo

Apparently Nix performs normalization on paths since the final slash is not included. So lets put the parenthesis differently:

nix-repl> ./foo + ("/" + name)
/home/bas.van.dijk/foo/bar

That's better! Now we can shorten this using some antiquotation:

nix-repl> ./foo + "/${name}"
/home/bas.van.dijk/foo/bar

Note that if you use import pkgs.path the path type of pkgs.path means that the contents will not be stored in /nix/store. However if you use import "${pkgs.path}", the pkgs.path gets interpolated as a string, and the pkgs.path then imported into the /nix/store. The former is more efficient than the latter. Remember you can always convert a path to a string with builtins.toString, but to do it other way you can use instead ./. + "string" or /. + "string".

@serokellcao

This comment has been minimized.

Copy link

serokellcao commented Jul 26, 2019

Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.