Nix(OS) for beginners, explained with concepts from Python

Hi there!

I have held a talk called “Nix(OS) for Python Developers” at PyCon Italia, recently. There was a lot of interest, and I have now managed to write a blog post as a summary of my findings.

I’m rather fresh to Nix and NixOS, so there might be mistakes or even fundamental misunderstandings in what I explain in that article and the related slides. My goal is to explain Nix for people who come from imperative languages, like Python.

I’d be happy about any constructive feedback. Thanks in advance!

5 Likes

Funny that although I do not code python, your explanation was the best yet. I really appreciate you sharing the analogies. And I also appreciate the tip of not expecting the same answers from many people. That knowledge helps me to just try things out. I am so happy with my nixos thinkpad. It is so stable. There is none of the nonsense one usually gets from Ubuntu.
I want to move into doing flakes for it. I will try this out and see if I can document my odyssey.
The process of documenting things to help oneself and others through the jungle is so tiring… so thanks.

1 Like

Nix functions can only have a single argument. Hence, when a function needs more than one parameter, you wrap curly brackets around the arguments (i.e. you use an attribute set). The same is true for the body when it contains more than a single assignment.

Technically, this isn’t true due to currying. This is completely valid:

first: second: first + second

I don’t think I can describe how currying works very well, but this is a great video on the lambda calculus that explained it well to me.

In other feedback, I’d love a table that compared the Nix syntax for something vs the Python syntax. This blog post does a great job with a table comparing the flake/non-flake ways of doing the same thing. Maybe something like that?

Technically, it’s true. It’s just a function returning another function.
Using python to express the same function:

f = lambda first: lambda second: first + second

# or
def ff(first):
    def f1(second):
        return first + second
    return f1

print(f(1)(2))   # 3
print(ff(1)(2))  # 3

2 Likes

That’s an interesting expectation. Do you have specific examples in mind?

I’ve since added tables that list popular commands and file system places. This is where I struggled coming from Ubuntu, which follows FHS.

Quick Transfer Of Existing Knowledge

What I try to show are the similarities and the differences of the Nix language compared to imperative languages, so that it’s easier to embrace Nix and NixOS. This is first and foremost the language syntaxlearn how to write and extend configuration logic – and then the concepts around tooling and processes – what is the function of a flake and how do I make it work – and here, analogies help to understand this quickly.

One of the dangers when you explain Nix, I figured, is that you lose yourself in academic explanations. This is natural – the choice of a functional language for the Nix core was certainly not a usability decision – but it turns off developers who “just want to get their job done”. For the latter you need to allow drawing conclusions from existing knowledge.