- app that is binary , so you can't build it from source, but is using dynamic libraries, then you can use autoPatchelfHook to tell nix to patch the binary to swap out the libraries to nix's version
- app that uses a lot of hard coded file system path that you would prefer not to patch them all out, then you can use buildFHSUserEnv to package/run the application/package in full FHS-compatible scenario
but the main point is that, nix is extreme in its approach, and the best approach in my opinion, is to do swapping step by step, ex:
you want to convert a existing project to nix, lets say nodejs
- you add the main deps in the default.nix (nodejs, yarn, high level utility needed to build)
- use sandBox false to allow building the app with yarn/npm in internet accessible(by default nix uses sandBox which disallow internet inside build step, which causes issue like npm install not working, etc)
- confirm working, then start using tool likes yarn2nix, other similar, and convert the packages itself to a usable set of nix packages
though I do agree that nix have the knowledge bias issue, and alot of my learning of nix involve me looking at the nixpkg sources itself and sometime even the nix's code
But 100% agreement that Nix needs a type checker!
The language is imperative, and the result is fully declarative. A pure functional description of this logic would worsen understanding instead of improving it, I believe, because when your conditionals affect multiple output variables, you have to duplicate the condition in multiple places.
Nix advantage here would be that is lazily evaluated, so there would be an additional benefit that only conditionals that are used are evaluated.
Functional benefit of Nix would be that Nix would know that a package doesn't need to be rebuilt if no inputs changed.
Side note Mozilla actually uses Nix internally, it appears that it is used for Rust and Firefox and most likely other things[1][2]
Yes, except that I can read this and I can't read nix. That's probably based on background, but more people are familiar with imperative than functional languages.
> Nix advantage here would be that is lazily evaluated, so there would be an additional benefit that only conditionals that are used are evaluated.
Agreed, although that's unlikely to be unique to nix?
> Functional benefit of Nix would be that Nix would know that a package doesn't need to be rebuilt if no inputs changed.
As would anything that can compare hashes. Or heck, make(1) can do as much.
Of course, language like Python is Turing Complete so you could implement the same functionality . You could also add functions that behave and perform operations lazily.
But you're missing the point though, those are properties that Nix provides natively that are tuned to what is required for this domain. Because the only side effect in nix is a derivation, and because language is lazily evaluated it is made for this purpose.
If you would use for example Python, you would need to write wrappers that would provide that behavior and it no longer would be Python, it would be some kind of DSL written in Python at that point and the risk then would be that it would be very easy to introduce iterative code that's not functional and not lazily evaluated (kind of like it happens with Chef recipes).
The Nix Language actually is not the problem here, the language is fairly simple, the biggest difficulty is actually nixpkgs which is huge and poorly documented. You often have to look at its code to understand what's going on. If it was written in Python you would have the same issues.
There is one thing that Nix Language could do better, a lot of people wish it was a typed language, because if it was typed it would be much easier to find a definitions, and wouldn't require as much of greping the code. But python again wouldn't help here.
Nix may be simple but it’s unfamiliar, and you’re already asking people to understand a novel package management system and everything about everything about their entire dependency tree, and these unknowns are collectively more confounding than the sum of their parts.
Python would help because it is familiar and gradually typed. That said, I’m open to any language that satisfies those properties (maybe also “composes nearly from expressions”).
Regarding the rest of your first paragraph, that's essentially what I said, you can write side effect free code in python, but it's so easy to introduce side effects if you're not paying attention.
I'm saying though that nix language isn't the hard part about nix, but perhaps you're right and it is one extra difficulty that just makes things harder.
But take a look at most o Nix derivations, majority of them end up being just an attribute set (aka dictionary, map etc in other languages)
Take look at https://nixos.org page (they changed it after this submission was posted, and it is better than the old page at showing what Nix can do)
Guix?
Even if you build Python-like and JS-like and etc syntax frontends for a hypothetical common backend, they will only be syntactically similar, but the semantics and standard libraries will be different than Python, JS, etc so there's really very little to be gained here.
And maybe it's even worse, since the whole goal is to allow a Python-like frontend to reference functions and variables defined by other frontends, the authors will probably have to understand certain aspects of all frontends. if those frontends are sufficiently similar and familiar (e.g., Python and JS) then there isn't much of a problem, but if you throw in an obscure syntax like Nix this becomes harder.
Grafting Python on top of the idiosyncrasies of how Nix does things would be a nightmare of impedance mismatch.
The mixing between parenthesis and braces and the lack of standard indentation makes some derivations really hard to read.
I can't give you an example right now, but I've been looking at the nixos modules that deal with creating NixOS images lately. So you can get an idea of the part of the codebase that gave me this experience.
For sure, you're absolutely right. I'm just saying that doing that in Python would have exacerbated the problem, not made it better. (Imagine someone taking the full power of Python and unleashing it on the derivation writing process, yuck.)
Any official package from Nix belongs to this single repository, making it easy to see what other packages are doing. If I want to see how python packaging is done, I simply search "python" in the nixpkgs repository.
It's also easier to grasp what is going on in nixpkgs than other packaging systems. The Nix expression language offers better readability than say, RPM spec files. Meanwhile the nixpkgs repository includes support for numerous build systems and frameworks. This combined allows you to create packages with minimal effort most of the time.
It's more focused on the result then on how you get there, but that result really impressed me.
yourthing_custom = yourthing.withPackages(ps: [ps.plugin1 ps.plugin2 ] )
Or are you stuck with how to implement it?