infinisil changed the topic of #nix-lang to: Channel for discussing Nix as a language - https://nixos.org/nix/manual/#chap-writing-nix-expressions - Logs: https://logs.nix.samueldr.com/nix-lang/
jeaye has joined #nix-lang
<jeaye> I have a list of attribute sets; how can I zipmap that into an attribute set given a key from each set in the list?
<infinisil> jeaye: Got an example?
<jeaye> i.e. (in EDN, since I suck at Nix) [{:foo "bar"} {:foo "spam"}] -> {"bar" {:foo "bar"} "spam" {:foo "spam"}}
<jeaye> For Clojure, I'd do (zipmap (map :foo items) items)
<infinisil> > :p lib.groupBy (x: x.foo) [ { foo = "bar"; } { foo = "spam"; } ]
<{^_^}> { bar = [ { foo = "bar"; } ]; spam = [ { foo = "spam"; } ]; }
<jeaye> The actual Nix code I need to change: https://gist.github.com/jeaye/c2aa524bcab9c7183af9314f9a2b2e6c
<jeaye> infinisil: Grouping will result in a list for each item, which isn't correct.
<infinisil> Well you can transform it into a non-list if you need to, but a list is the thing that makes sense for such an operation
<infinisil> > :p lib.groupBy (x: x.foo) [ { foo = "bar"; } { foo = "bar"; } ]
<jeaye> In the actual Nix code, virtualHosts is no longer a list of attribute sets. It's now an attribute set itself.
<{^_^}> { bar = [ { foo = "bar"; } { foo = "bar"; } ]; }
<infinisil> Because you can have duplicates
<jeaye> In this case, there won't be duplicates.
<jeaye> That's probably why httpd.virtualHosts was changed into an attribute set. :P
<infinisil> Then you can `lib.mapAttrs lib.head` to transform each value into the first element
<infinisil> I'm not sure I understand where you're trying to use such code hmm
<jeaye> I'll share the whole file link so you can see.
<jeaye> The API changed for httpd and it's blocking up server upgrade.
<jeaye> So, just setting up an httpd virtual host and index file for a bunch of domains.
<infinisil> Ah I see, hold on
<jeaye> If Nix had zipmap, I could use something like: (zipmap domains (map makeVirtualHost domains))
<infinisil> Try that out
<jeaye> Ah, that's basically a zipmap. Expanding a list of pairs into a map.
<jeaye> infinisil: Thanks so much for helping me.
<infinisil> Ah I see
<infinisil> :D
<jeaye> Nix is so opaque to me.
<infinisil> There isn't too much to it actually, the core language is pretty simple
<jeaye> People say that, but they're typically coming from a Haskell or ML background.
<infinisil> The nixpkgs library (lib here) contains a whole bunch of utility functions though, and these can be very tricky to figure out
<infinisil> Nix is *very* different from Haskell or ML, contrary to popular belief!
<infinisil> The only thing it shares is the functional purity
<jeaye> I write functional code for a living (mainly Clojure) and have been running NixOS for 6 years. Nix has just never clicked.
<infinisil> I believe if you take some time to really learn about it, it wouldn't be so bad :)
<simpson> The main difficulty that I found was that, compared to e.g. Scheme or Haskell, Nix generally doesn't have element-at-a-time looping over lists. So one must instead work through map/filter operations.
<jeaye> map/filter/reduce are no issue for me. The issue is that the language isn't approachable as something that's easy to use, both in terms of documentation, logging, and the environment in which one can play and explore.
<simpson> Yeah. I am heavily dependent on the REPL.
<jeaye> Yeah, in a Clojure/Lisp REPL, searching for docs and other functions is trivial. Tooling has auto-completion of functions, and logging values is easy.
<infinisil> jeaye: Do you know about `nix repl`?
<jeaye> Or, as a different example, for C++, I can refer to cppref for complete documentation and references: https://en.cppreference.com/w/cpp/string/basic_string/to_string and then use an online code compiler for tinkering without needing to worry about the environment.
<ekleog> I wonder whether everyone's being very polite or it's just me who thinks that the language, tooling and documentation around it is a huge pile of [insert here some expletive that's fun yet explicit, idk english well enough to know one]? (which is all mostly due to not enough people caring about it, hello people how are you doing?)
<ekleog> ok that being said I'll go back to not improving on the language because otherwise trolling would be so much less fun
<ekleog> (if you wonder what degree of sarcasm I'm putting in these sentences, even I do not actually know)
<infinisil> I think it's mainly tooling and docs, not the language itsel/f
<ekleog> yeaaaah well priority of the `or` “operator”? :p
<infinisil> I guess the builtins could be a bit better, but other than that I don't think the language itself is problematic
<infinisil> ekleog: There are some small warts, but generally it's fine imo!
<ekleog> builtins are inconsistently named (fetchgit but attrNames)
<infinisil> It's fetchGit though
<ekleog> oh this one is fetchGit? I never remember which one is which between {builtins,lib}.{fetchgit,fetchGit}
<ekleog> sorry then ^^'
<infinisil> builtins.fetchGit (or just fetchGit), and pkgs.fetchgit :)
<jeaye> builtins.builtins.builtins.builtins.fetchGit you mean.
<ekleog> ok so it's nixpkgs that's just broken there ^^'
<ekleog> oooh yes the old versions of map vs. builtins.map
<infinisil> Yeah, nixpkgs is a huge pile of [word], not gonna lie!
<infinisil> "old" versions?
<ekleog> like, the fact that map is like builtins.map already
<infinisil> Ah yeah, there are a couple like that
<ekleog> the debugging of infinite loops, and debugging in general (poke poke haskell's $ operator for trace at least)
<ekleog> docstrings
<infinisil> Yeah debugging is bad..
<infinisil> Haskell's $ op doesn't have anything to do with tracing though?
<ekleog> no, but it'd make it so much easier to just add `builtins.traceVal $` and see the value of things without having to figure out where to close the parenthesis
<ekleog> uh lib.traceVal *
<ekleog> then, a clean way to import only a subset of values from a set into scope (no the weird trick with let inherit or let with, I don't remember, doesn't count as clean :p)
<infinisil> `let inherit (values) sub set; in ...` isn't good?
<ekleog> ooooooh yes the order of arguments for builtins.elem and builtins.elemAt
<ekleog> hmm ok maybe it's actually good enough and I'm just not used to it enough
<infinisil> I do want to make a PR to support list element access like `[ 0 1 ].0` :D
<ekleog> oooh right list syntax
<ekleog> thank you for the reminder :p
<ekleog> the syntax for importing files is very manual, compared to eg. rust's module system that makes everything transparent (`use foo::{bar, baz};` vs. `let inherit (import ./foo.nix) bar baz; in`)
<ekleog> I mean, overall nix is somewhere below PHP in my “quality of language” list, because I can't think of any complaint against PHP that wouldn't apply to nix
<ekleog> and I mean, to me it's OK because I'm using nix not for the language but for the concepts that are behind the language
<jeaye> Nix has always been my one key gripe with NixOS and it's _the_ reason why I don't think it'll catch on nearly enough as it deserves. People shouldn't have to learn such an opaque DSL to configure their system. From what I know, the benefits of NixOS's design have absolutely nothing to do with a custom language. So why not use something saner, which already exists?
<ekleog> ^ that, though I'm far from sure something that would fit the bill already exists (we kind of need laziness, and I'm far from convinced haskell or lisp-like syntaxes are a good match for it)
<ekleog> the good thing is, AFAIR the nix language is entirely implement client-side, which means that it should not be backwards-compat-breaking to implement a nix-lang-v2, have the tooling automatically detect between nix and nix-v2, and then slowly infect nixpkgs with it
<infinisil> Frankly, I think you're overestimating how opaque nix is jeaye. There's really not a lot to the core language, it's a simple lambda calculus
<infinisil> atoms, lists, objects and functions
<ekleog> and derivations, and strings with context
<infinisil> Derivations are just objects in the language, strings with context are just strings, and you don't need to worry about the context
<ekleog> (right that reminds me about the string context, a part of the language I think I still don't actually understand)
<jeaye> infinisil: It's opaque due to the syntax, documentation, tooling, environment, and community more so than it is the functions within its stdlib.
<infinisil> Okay the syntax I can agree a bit with, there are some odd bits about it
<infinisil> But everything else is not a problem of the language, but rather it's ecosystem
<jeaye> With that said, I came in here for help and, infinisil, you were both kind and helpful. So I don't want to upset you at all.
<infinisil> I'm not upset at all, all good discussion here :)
<ekleog> let's not throw [word] at each other :3
<ekleog> (okay I'm already out :p)
<jeaye> I just think the Nix language is dead weight which Nix and NixOS should drop in favor of an existing general purpose lang. I think, rather than saying what's bad about it, the simplest question exists: why does it need to exist?
<infinisil> Yeah about that, there's some key features about Nix which are required for it to work
<infinisil> And none of the existing languages have that
<ekleog> AFAIK the only workable alternative would be a lisp language, as we need it to be lazy and dynamic for nixpkgs to work (unless we want to drop nixpkgs, which won't happen)
<infinisil> One key feature is string context and derivations
<ekleog> And well… guix did the thing with a lisp language and is even less successful than nix, so… ^^'
<ekleog> (s/dynamic/dynamically typed/)
<infinisil> Another key feature is purity
<jeaye> Guix is less successful due to its fanatic approach to FLOSS, I think.
<infinisil> And I think purity is also where guix fails. I think they're just telling people to keep their code pure, but it can't really be enforced (somebody correct me if that's wrong)
<jeaye> Does it need to be enforced?
<ekleog> don't know enough about guix to correct, sorry :/
<infinisil> Nix's purity ensures that the same Nix expression evaluates to the same build instructions everywhere
<jeaye> I have had a note in my todo/ideas for a handful of years to make a Clojure -> Nix transpiler. Maybe this is the year.
<ekleog> TBF I've wondered a fair number of times whether it'd be possible to incrementally replace nix with something like racket — I'm relatively sure we could force racket to be pure (when one controls the stdlib it's usually not that hard), but that's a lot of work
<jeaye> I would <3 that so much.
<jeaye> I would also fund it, if someone starts it.
<infinisil> I'd also love to see what a reimagined Nix could look like
<infinisil> There is Nickel (https://github.com/tweag/nickel), but I don't think it's meant as a Nix replacement
<infinisil> Though it is also pure and very similar to Nix. Main feature missing for it to replace Nix is string context and derivations I think
<ekleog> going the racket way would also give us gradual typing for ~free (or clojure too maybe? looks like it's getting gradual typing nowadays)
<jeaye> Hm... I have more time on my hands these days, having left my startup for a larger company. Seriously considering the Clojure -> Nix interop or transpiler now.
<jeaye> ekleog: No gradual typing in Clojure, really. TypedClojure isn't nearly as successful as TypedRacket. The more typical approach is to use spec, which provides run-time contract validation.
<jeaye> As well as instrumentation of functions to make that validation automagic for all inputs and outputs.
<ekleog> I'd say if you start thinking about it, maybe start by taking random files in nixpkgs and seeing how they'd look once converted to clojure/racket, to check whether it'd actually be an improvement (and… well… maybe also ask people who are not yet familiar with clojure to have a look at it :p)
<ekleog> the big issue will be in making such a change approved by the community, in part because picking clojure will mean not picking racket and reciprocally
<jeaye> hmmm
<ekleog> (see the time it took for the new documentation format RFC to land despite the fact mostly everyone hated the current xml format… and the documentation format will most likely be much easier to change than a change like nix-lang-v2)
<ekleog> there will certainly be people who'd rather have something like nickel as nix-lang-v2, despite the fact it'd mean we're back to square 1 in tooling, having to develop it ourselves
<ekleog> Anyway, just want to say “don't rush to implementation” because the community is slow-moving and if you don't gather a significant number of approvals beforehand there's significant risk the implementation will end up having little impact :)
<ekleog> (though a PoC would also definitely help people understand what they'd gain too, so… YMMV)
<ekleog> (like… random thought, but having a bidirectional transpiler would allow to easily let people understand the tooling benefits by showing them in practice over the whole nixpkgs repo)
<infinisil> ekleog: There's LSP development happening for nickel I think, so that's at least something :)
<ekleog> yeaaaah well I mean it's tooling we have to maintain ourselves, despite the fact that's it's better tooling than nix ^^'
<infinisil> I think the best way forward for Nix is to slowly improve the existing language. Removing gotchas, adding useful features, improving tooling, writing docs, etc.
<infinisil> Anything else is unrealistic with nixpkgs' size
<infinisil> imo at least
<ekleog> well, something like the .c / .cpp “migration” could very much work for nixpkgs I think, so long as it's possible to seamlessly integrate the two languages
<ekleog> we wouldn't have all the benefits of the tooling right away because a big part of the codebase would still be nix, but it sounds in the realm of the possible at least
<ekleog> that being said, I'm with you that what probably would be the best immediately-beneficial thing would be docstrings and a good way to see the generated documentation, for all the functions and maybe packages in nixpkgs
<ekleog> (question then being whether it's easier to integrate that in nix, or to just introduce another syntax of nix with a language that already has that… and I wouldn't be confident either way)
<simpson> jeaye: I would challenge the assumption that we *want* a comfortable general-purpose language for writing Nix expressions.
<simpson> I don't think that anybody should really desire much code to be written in Nix.
<jeaye> That limits NixOS to not only Linux users, not only people who want to try novel distros, not only programmers, but also people with experience or readiness to learn a declarative, lazy DSL which they've never seen before and which they'll never use outside of Nix.
<jeaye> Yep, any day.
<jeaye> Compared to the assumption that they want to learn the awkward syntax of a purely functional ML-like language, I'll take that bet.
<simpson> It's trivial to argue that Schemers are *also* limited to folks who are willing to try out new DSLs, since it's not really possible to use Somebody Else's Scheme Macros without essentially learning the corresponding DSL.
<simpson> But I'd normally rather argue that it's not important whether a distro's audience is limited; what matters is whether the distro's tooling is giving its audience a satisfying experience.
<simpson> (Otherwise, language designers are subject to a sort of heckler's veto, right?)
kini has quit [Remote host closed the connection]
kini has joined #nix-lang
kini has quit [Remote host closed the connection]
kini has joined #nix-lang
<jeaye> I see your point.
jared-w has quit [Ping timeout: 258 seconds]
jared-w has joined #nix-lang
kini has quit [Remote host closed the connection]
kini has joined #nix-lang
evanjs- has joined #nix-lang
evanjs has quit [Ping timeout: 256 seconds]
jeaye has quit [Ping timeout: 256 seconds]
jeaye has joined #nix-lang
kini has quit [Remote host closed the connection]
kini has joined #nix-lang
rajivr has joined #nix-lang
__monty__ has joined #nix-lang
rajivr has quit [Quit: Connection closed for inactivity]
__monty__ has quit [Quit: leaving]
Dotz0cat has quit [Ping timeout: 260 seconds]
Dotz0cat has joined #nix-lang
Dotz0cat has quit [Remote host closed the connection]
Dotz0cat has joined #nix-lang
Dotz0cat has quit [Ping timeout: 260 seconds]
Dotz0cat has joined #nix-lang