NoobQuestion: whats wrong with my variable declaration?

Hi! I’m new to Nixos and have just installed it on my secondary machine and am trying to learn.

I’ve seen in many places we’re suggested to define variables with a let keyword. However I’ve never gotten that to work and there seems to be some missunderstanding on my part of this very basic topic.

here’s an excerpt from my configuration.nix that I can’t quite understand why it doesn’t work:

  # List packages installed in system profile. To search, run:
  # $ nix search wget
   nixpkgs.config.allowUnfree = true;

  let jdk = pkgs.callpackage /etc/nixos/jdk11.nix {};
    in self; 
   environment.systemPackages = with pkgs; [
. . .

as you can see I’m trying here to define a custom package containing java11, nothing too fancy. however when I run nixos-rebuild test I am met with:

[anders@nixos:~]$ nixos-rebuild test
error: syntax error, unexpected LET, at /etc/nixos/configuration.nix:76:3
(use '--show-trace' to show detailed location information)
building Nix...
error: syntax error, unexpected LET, at /etc/nixos/configuration.nix:76:3
(use '--show-trace' to show detailed location information)
building the system configuration...
error: syntax error, unexpected LET, at /etc/nixos/configuration.nix:76:3
(use '--show-trace' to show detailed location information)

my question is then: whats wrong with the above code, and how does one correctly define a variable?

sorry about this question being so incredibly nooby, I can assure you I feel suitably ashamed for asking this, but it seems like everyone else is using this syntax and I cant understand what I’m doing wrong.

It’s better if you post the entire file, here your let usage doesn’t seem useful at all… from what can I understand from this fragment, you could have just written:

...
jdk = pkgs.callpackage /etc/nixos/jdk11.nix {};
environment.systemPackages = with pkgs; [
...

You can’t use let in the middle of an attrset. And even if you could, in self doesn’t look right; what’s self, and why did you bind jdk without using it?

It’s hard to tell you what you should actually write without knowing what your goal is here.

so i’d be using the let jdk further down, inside sytempkgs. the goal to define my own package and install it basicaly

When you write let x = y; in z you only make x available in the expression z. In your example you are making jdk available in self, whatever that means. The error comes because all the things in an attrset must be of the form attrName = expression.

The two ways you could do this are to either:

  1. Use the let statement correctly i.e.
environment.systemPackages = let jdk = pkgs.callpackage /etc/nixos/jdk11.nix {};
  in with pkgs; [
  ...
  jdk
  ...
];

Here the let statement makes jdk available in the statement following in (which is `with pkgs; [ … jdk … ]; here)

  1. Use an overlay to add your package. You can get some information here Overlays - NixOS Wiki . These allow you to modify the package set your configuration uses and may be the neater way to do what you are trying to do.

You don’t even really need the let here. You can just do

environment.systemPackages = with pkgs; [
  hello
  (callPackage /etc/nixos/jdk11.nix {})
];
1 Like

If you did combine with pkgs and let you’d want to do so in the other order in case pkgs already contains a field named jdk.

environment.systemPackages = with pkgs;
  let jdk = pkgs.callpackage /etc/nixos/jdk11.nix;
  in [
    …
    jdk
    …
  ];

That said I agree with @JohnAZoidberg in that it’s simpler just to ditch the let in this case.

1 Like