Skip to content

Instantly share code, notes, and snippets.

@infinisil
Created July 3, 2018 23:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save infinisil/f71bf7e0d76816230087473eedeaa7f4 to your computer and use it in GitHub Desktop.
Save infinisil/f71bf7e0d76816230087473eedeaa7f4 to your computer and use it in GitHub Desktop.
[23:37:03] *** Joins: elvishjerricco (sid237756@gateway/web/irccloud.com/x-umuwdmjgrvrevwbc)
[23:37:13] *** Joins: mpickering (sid78412@gateway/web/irccloud.com/x-wquekemwbsynjxxl)
[23:37:23] <mpickering> The birth of a new channel, how exciting
[23:37:29] <infinisil> :P
[23:37:55] <infinisil> Probably gonna give gchristensen the rights over it if it becomes something
[23:38:00] <elvishjerricco> .extend also isn't actually mutating anything, but it's very hard to keep track of who's using which extended set
[23:38:29] <mpickering> How do you usually use extends?
[23:38:36] <elvishjerricco> It'd be a little bit better if `extend` weren't installed directly in the attrset, because then we wouldn't have issues like the `override` / `extend` conflict
[23:38:43] <mpickering> Do you have an overlay which overwrites haskellPackages?
[23:38:44] <infinisil> I find it really useful, the self super abstraction
[23:38:56] <elvishjerricco> Yea, the self super abstraction is great.
[23:39:13] <infinisil> I plan to rewrite my nix evaluation bot to use extends, and tests have been quite successful
[23:39:15] <elvishjerricco> But I tend to prefer the `overlays` method to the `extends` method, which is subtly different
[23:39:27] <mpickering> I don't see what the difference is
[23:39:37] <infinisil> Me neither
[23:39:42] <elvishjerricco> Just in how you actually apply an extension.
[23:40:19] <elvishjerricco> You have to do it up front. The nixpkgs set itself isn't more than just a function that takes its requirements as arguments. haskellPackages.extend makes haskellPackages more of a mutable object
[23:40:54] <mpickering> ok, that's an annoying thing about nixpkgs then?
[23:40:58] * infinisil doesn't quite get your point
[23:41:10] <mpickering> infinisil: I think the point is that you can't continually extend a nixpkgs set
[23:41:15] <elvishjerricco> right
[23:41:19] <mpickering> but you can .extend .extend .extend a haskell package set
[23:41:28] <infinisil> Ah I see
[23:41:32] <elvishjerricco> That, and the fact that extend has to be installed in haskellPackages
[23:41:43] <elvishjerricco> which is deeply problematic as you start to compose ideas with the same installation idea
[23:42:57] <mpickering> .extend is better than the old way though for haskell packages
[23:43:25] <mpickering> as they are applied cumulatively rather than the overrides argument which is not really compsable
[23:43:36] <mpickering> and it's the same for nixpkgs so I guess I disagree with you
[23:43:38] <elvishjerricco> mpickering: `overrides` can be composed
[23:43:49] <elvishjerricco> `overlays` are also composed
[23:43:50] <mpickering> with a really annoying pattern
[23:44:08] <elvishjerricco> mpickering: yea, but `override` itself is the same problem as `extend` so I have the same distaste for it I guess :P
[23:44:08] <mpickering> Like this pattern for extending a haskell package set which is propagated - https://github.com/Gabriel439/haskell-nix/tree/master/project1#changing-versions
[23:44:33] <mpickering> I was referring to the `overrides` argument to the haskell package set
[23:44:45] <elvishjerricco> mpickering: Right, but using that depends on `override`
[23:45:55] <elvishjerricco> mpickering: But you can do `haskellPackages.override (old: { overrides = composeExtensions (old.overrides or (_: _: {})) newOverrides; })` to compose it. It's painful but it's functionally the same as extend, except that it doesn't break future `override` calls
[23:46:05] <infinisil> I want {^_^} in here to use nix evaluation..
[23:46:35] <mpickering> this is my precise point though, if that's the recommended way
[23:46:43] <mpickering> the language has to make it easier than this horrible thing
[23:47:06] <mpickering> infinisil: What's your opinion about my suggestion from before? `rec self: { foo = 10; bar = self.foo + 20; }`
[23:47:14] <elvishjerricco> mpickering: Well I think it just shows how bad these non-composable functions that install themselves are
[23:47:17] <elvishjerricco> as a general concept
[23:47:31] <infinisil> mpickering: To abandon rec { ... } and require you to use that syntax?
[23:47:45] <mpickering> yes hypothetically
[23:48:12] <infinisil> I mean, you can still get s/self.foo/foo by doing `rec self: with self; { ...`
[23:48:17] <mpickering> or even, `rec super: self: { foo = 10; bar = self.foo; baz = super.foo }`
[23:48:39] <infinisil> So that would evaluate to an attrset?
[23:48:42] <infinisil> Or a function?
[23:48:49] <mpickering> An attrset
[23:48:53] <elvishjerricco> eelco had something for this stuff in a gist somewhere...
[23:48:56] <mpickering> by taking the fixpoint
[23:49:07] <elvishjerricco> He wanted a `{{ ... }}` syntax that ultimately encapsulated `self: super:` stuff
[23:49:10] <mpickering> Essentially by calling `makeExtensible` on the function
[23:49:12] <elvishjerricco> but without the function stuff
[23:49:18] <infinisil> But you can't get a fixed point when you don't have any super to start with
[23:49:35] <elvishjerricco> infinisil: initial super would just be {} most likely
[23:49:46] <infinisil> Hmm..
[23:50:07] <infinisil> Still don't get how that's useful, how could you compose this?
[23:50:24] <mpickering> the point is then all attrsets support `extend` immediately
[23:50:37] <infinisil> Ahh
[23:50:55] <infinisil> The extensible attrsets thing
[23:51:08] <infinisil> <link of *the gist* here>
[23:51:10] <mpickering> starting from the premise that we shouldn't have recursive attribute sets to begin with
[23:51:23] <infinisil> https://gist.github.com/edolstra/29ce9d8ea399b703a7023073b0dbc00d
[23:52:01] <elvishjerricco> Yea I rather like that proposal
[23:52:02] <infinisil> Hmm.., I don't dislike this idea
[23:52:23] <elvishjerricco> Particularly because there's no `extend` installed. The value is fundamentally just a function being repeatedly composed
[23:52:25] <elvishjerricco> Much more logically sound
[23:52:52] <infinisil> Hold on, how does {{ }} work exactly
[23:53:02] <infinisil> There's an example
[23:53:10] <infinisil> base = {{ x = 123; y = x; }}
[23:53:40] <infinisil> So that would imply it's something like `self: super: with self; { x = 123; y = x; }`
[23:53:48] <elvishjerricco> Yea, I think that's the design
[23:53:55] <mpickering> this seems too implicit for my liking
[23:53:56] <elvishjerricco> Not personally a fan of the dynamic scoping
[23:54:03] <infinisil> Ah right
[23:54:16] <elvishjerricco> `with` already makes Nix's scoping rules very arcane :P
[23:54:25] <infinisil> Was a bit confused because for my nixbot I'm planning to use `self: super: with super;`
[23:54:25] <mpickering> this will make it even easier to write infinite recursion
[23:55:10] <elvishjerricco> Though I don't think that proposal has a concept of `super`, actually :/
[23:55:26] <infinisil> How about {{ x = 123; y = .x }}
[23:55:37] <infinisil> . to refer to self
[23:55:52] <mpickering> how about just giving self a name and using that heh
[23:56:03] <elvishjerricco> We also need access to super
[23:56:12] <mpickering> indeed
[23:56:39] <infinisil> Does the proposal there say anything about how to do this?
[23:56:47] <elvishjerricco> Don't think so
[23:57:05] <infinisil> Oh right, I think it's only a normal fixed point
[23:57:13] <mpickering> I would rather start again with my own language that compiled to nix rather than extend the nix language
[23:57:21] <mpickering> there are quite a lot of poorly specified parts
[23:57:33] <infinisil> Which one might that be?
[23:57:54] <infinisil> It's kind of impossible to switch though, nixpkgs is kinda settled now
[23:58:26] <elvishjerricco> How would the `{{ ... }}` syntax idea be used for e.g. mkDerivation?
[23:58:46] <elvishjerricco> Or really any function where you want its output but you also want to extend its arguments?
[23:59:16] <mpickering> infinisil: Not at all, we are still in early days here.
[23:59:46] <mpickering> elvishjerricco: How do you mean extend the arguments?
[00:00:13] <infinisil> I don't think it would go well to just switch the language
[00:00:27] <elvishjerricco> mpickering: Currently we have `foo.overrideAttrs` (yet ANOTHER self-installing function) for taking the result of `mkDerivation` and re-calling `mkDerivation` with modified arguments
[00:00:34] <elvishjerricco> I think that pattern needs to be encapsulated
[00:00:51] <mpickering> ah you're talking about that pattern yep
[00:00:58] <mpickering> the same thing for overrideCabal
[00:01:28] <mpickering> infinisil: You can use IFD to write your nix in whatever language you like :) ?
[00:02:09] <infinisil> Heh, I guess
[00:02:15] <elvishjerricco> I guess my question could be answered with `{{ name = "foo"; src = bar; outPath = mkDerivation .; }}`
[00:02:28] <elvishjerricco> Or whatever `self` syntax we get
[00:02:57] <elvishjerricco> But that only works for things whose `outPath` is all we care about
[00:03:00] <infinisil> Heh, how about this: {super{ foo = self.bar; bar = super.bar + 1; }self}
[00:03:01] <mpickering> override is precisely the same pattern right?
[00:03:14] <mpickering> interesting infinisil ....
[00:03:21] <infinisil> It even makes sense!
[00:03:25] <mpickering> doesn't read very well ltr or ... rtl
[00:03:45] <elvishjerricco> mpickering: override is different in that it has too bookkeep about installed functions and does not preserve arguments in the output
[00:04:47] <elvishjerricco> On a related note: I've often found myself wanting some idea of `super` in the NixOS module system, but there is no logical order so there's no way for it to make sense.
[00:04:53] <infinisil> So hold on, the problem with these extensible attrsets is that we need some syntax that evaluates to a `self: super: { ... }`, but without always having to specify self and super, but only when we actually need it?
[00:05:22] <infinisil> elvishjerricco: All options are intertwined, they don't have a linear order
[00:05:28] <mpickering> I have no idea what the problem is. Writing self: super: is not very verbose is it heh
[00:05:34] <elvishjerricco> infinisil: Right but there is an order of modules
[00:05:46] <infinisil> But using the `config` argument is like a `self`
[00:06:03] <elvishjerricco> Right. It'd be nice if I could modify a config from a module that I import
[00:06:43] <infinisil> mpickering: But if you want to be able to customize all attribute sets, then these arguments would get pretty annoying, right?
[00:07:11] <mpickering> Nope, because they make answering questions about what you mean to refer to easy to answer
[00:07:35] <infinisil> But you don't need the arguments all the time
[00:07:56] <infinisil> E.g. when I want to make an extensible attribute `src = {{ url = https://..; sha256 = "..."; }}`
[00:08:09] <infinisil> I don't want to specify self and super when I don't need them
[00:08:16] <mpickering> ok fine
[00:08:22] <mpickering> I will give you that one
[00:08:31] <infinisil> Heh
[00:08:38] <elvishjerricco> You could argue it's alright to just use normal attrsets in that case
[00:08:51] <infinisil> This src attribute is probably one of the most compelling arguments for this, because it would be so useful to extend that
[00:08:55] <elvishjerricco> The burden is on the extender to make it extensible
[00:09:10] <elvishjerricco> `{ foo = bar; } // {{ baz = .foo; }}`
[00:10:45] <infinisil> > The burden is on the extender to make it extensible
[00:10:49] <infinisil> I don't get what you mean by that
[00:11:03] <infinisil> You mean the mkDerivation definition?
[00:11:07] <infinisil> In the src case
[00:11:58] <infinisil> elvishjerricco: ^
[00:12:39] <elvishjerricco> Oh I just meant that if you aren't referring to any self / super variables, there's no need to use a recursive attr set.
[00:12:58] <elvishjerricco> If someone wants to add attrs that do require recursive references, they can make it so
[00:15:16] <elvishjerricco> Bleh. I wish we could --dry-run IFD phases
[00:15:37] <infinisil> I'm thinking of this: `hello = mkDerivation { name = "hello-${version}"; version = "1.0"; src = fetchurl { url = "https://example.com/hello/${version}"; sha256 = "..."; }; }`
[00:16:05] <infinisil> And being able to change the url by overriding it with a different version (let's ignore the sha256 for now)
[00:16:19] <elvishjerricco> infinisil: Yea I think that depends on how we would solve the intermediate function problem
[00:16:28] <elvishjerricco> `mkDerivation` could easily force its argument to be made extensible
[00:17:36] <infinisil> Hmm
[00:17:45] <infinisil> There's kind of lots of problems to solve
[00:17:54] <elvishjerricco> Yep :/
[00:17:55] <infinisil> And I don't see a nice solution in sight
[01:21:10] *** Joins: gchristensen (~gchristen@unaffiliated/grahamc)
[01:21:14] <gchristensen> infinisil: +o me?
[01:21:24] *** Joins: MichaelRaskin (~MichaelRa@147.210.22.169)
[01:21:29] <infinisil> Umm, how do I do that
[01:21:40] <gchristensen> /mode +o #gchristensen probably
[01:21:43] <gchristensen> oops
[01:21:46] <gchristensen> /mode +o gchristensen probably
[01:21:48] *** infinisil sets mode: +o gchristensen
[01:21:53] *** ChanServ sets mode: -s+tc
[01:22:30] *** Parts: gchristensen (~gchristen@unaffiliated/grahamc) ("WeeChat 2.0")
[01:23:27] *** Joins: samueldr (~samueldr@unaffiliated/samueldr)
[01:26:24] *** Joins: {`-`} (~nixos-use@aeropolis.popalot.net)
[01:26:41] <samueldr> everything is now logged
[01:27:07] <samueldr> infinisil: if you want to add the link to the topic https://logs.nix.samueldr.com/nix-lang/
[01:28:41] *** infinisil changes topic 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/'
[01:28:46] <infinisil> samueldr: Thank :D
[01:29:39] <infinisil> How do I get rid of this @ in front of my name while I'm at it?
[01:30:37] <samueldr> /mode #nix-lang -o infinisil
[01:30:45] *** infinisil sets mode: -o infinisil
[01:30:53] <infinisil> Nice
[01:31:19] <infinisil> samueldr: Can you manually add some log entries? We had a decent discussion earlier today (the first one in this channel actually)
[01:31:26] <infinisil> I can send you the logs
[01:32:36] <samueldr> I technically can, but it's uh, a convoluted process
[01:33:01] <samueldr> though, you could always gist it, (secret gist if you don't want it in the list of public gists) and link it
[01:33:07] <samueldr> at least it would be linked from here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment