4 ms·
I'm using nixos for years, still couldn't grasp the language itself enough. I accepted that it's not for us, who are not familiar with functional programming. L
by seqizz 5y ago
I'm using nixos for years, still couldn't grasp the language itself enough. I accepted that it's not for us, who are not familiar with functional programming. Like, what is even this: https://github.com/Ryunaq/dotfiles/blob/b132f79e2042d6ef75008d666ba12306ad21d427/flake.nix#L60-L66 https://github.com/Ryunaq/dotfiles/blob/b132f79e2042d6ef7500...
- deleted 5y ago[deleted]
- chriswarbo 5y agoIt's a list of "overlays" (functions of two arguments, which return a key/value set). Overlays make it easy to overrides and replace things. If you prefer imperative programming, then think of it being used like this: const result = defaultNixpkgsSet; for (overlay in overlays) { // Merge the overlay's return value into the results value result := result.merge(overlay( result, // Give each overlay a reference to result result.copy() // Also give a snapshot of the contents so-far )) } return result; Consider an overlay something like this: function(result, snapshot) { return { maven = snapshot.maven.override({ jre = result.jre8; }) }; } Merging this into the 'result' will replace the 'maven' definition. That new definition is the same as the old one ('snapshot.maven'), but it will be using 'jre8' instead of the default. Two things to note: - We're using 'result.jre8', which will include any overrides made to 'jre8' (by other overlays, even those being applied after this one!) - We're using 'snapshot.maven', since using 'result.maven' would cause an infinite loop (since 'result.maven' depends on the output of this override!) In that link, they're calling their arguments 'final' and 'prev' instead of 'result' and 'snapshot', but the idea's the same. Most overlays call their arguments 'self' and 'super', but I avoided them in this explanation since those names have specific meanings in other languages (they're literally just variable names in Nix).
- zaphar 5y agothe result infinite loop issue is easily the most confusing part of nix. It works because nix is a lazy functional language. But I'm not particularly sold on that laziness being useful since it leads to awkward hacks like the two arguments to an overlay function. It has the one benefit of allowing you to not care about the order that overlays get called in. However it does that by giving your code magical come from semantics that make debugging a problem harder than it needs to be. I think the nix lazy semantics would actually have been better left out in favor of clearer dependency semantics. In a way the clearer dependency semantics of flakes are are driving the reason they are increasing in adoption so much. In essence they work around the problems introduced by overly clever usage of laziness in a nix package.
- chriswarbo 5y ago> But I'm not particularly sold on that laziness being useful since it leads to awkward hacks like the two arguments to an overlay function. It has the one benefit of allowing you to not care about the order that overlays get called in. However it does that by giving your code magical come from semantics that make debugging a problem harder than it needs to be. I don't consider it an awkward hack; it's a very standard least-fixed-point calculation. Developers these days seem comfortable-enough with 'self' and 'super' in OOP; that fixed-point pattern is essentially the same, but without shoe-horning magic keywords into the language.
- zaphar 5y agoI think you could get 99% of the value of an overlay as a simple fold or map over the result. Introducing the second argument feels very much like a workaround to allow you to avoid the infinite loop.
- seqizz 5y agoThank you. That was clear, now I can understand a bit better. But I feel like not clever enough while looking at to this block of code. .. so the sharedOverlays list has one element, which has our in it, which will have a .lib attribute pointing to lib defined above?