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/
__monty__ has joined #nix-lang
infinisil has quit [Quit: Configuring ZNC, sorry for the joins/quits!]
infinisil has joined #nix-lang
infinisil has quit [Client Quit]
infinisil has joined #nix-lang
infinisil has quit [Quit: Configuring ZNC, sorry for the joins/quits!]
infinisil has joined #nix-lang
infinisil has quit [Remote host closed the connection]
infinisil has joined #nix-lang
infinisil has quit [Quit: Configuring ZNC, sorry for the joins/quits!]
infinisil has joined #nix-lang
infinisil has quit [Client Quit]
infinisil has joined #nix-lang
infinisil has quit [Quit: Configuring ZNC, sorry for the joins/quits!]
infinisil has joined #nix-lang
MichaelRaskin has joined #nix-lang
<ekleog> ughhhhhh
<ekleog> just got hit by the fact that in { a ? "a" } @ b: , b doesn't necessarily contain the key `a`
* ekleog wonders whether that could be considered as a bug and fixed, it's just so meaningless
<ekleog> looks like it won't :( https://github.com/NixOS/nix/issues/745
<{^_^}> nix#745 (by anderspapitto, 2 years ago, closed): inconsistent and buggy behavior of argument sets with aliases
<infinisil> Hmm..
<ekleog> that's maybe the worst stupid-ness I've seen in nix up to now (though it's maybe just because I'm currently hit by it that I think this
<ekleog> )
<ekleog> > let foo = { a ? "a" } @ b: b.a; in foo {}
<{^_^}> attribute 'a' missing, at (string):197:28
<infinisil> So you'd want it to be like
<infinisil> > let foo = { a ? "a" } @ b: let b' = b // { inherit a; }; in b'.a; in foo {}
<{^_^}> "a"
<ekleog> yeah
* infinisil tries to think of a reason the current behaviour would be desired
<ekleog> basically, to define an alias to what's before the @, not to define an alias to the argument
<ekleog> oh well I think you can make hacks to get it a use… like, differentiating between foo { a = "a"; } and foo {} in the example above, but… why?
<infinisil> Ah yes, actually I'm using this!
<ekleog> (and specifically, why such a confusing syntax and why no syntax for the intuitive thing?)
<infinisil> In my deprecation branch for the deprecation RFC (still need to respond to oxij there)
<{^_^}> rfcs#33 (by Infinisil, 4 weeks ago, open): [RFC 0033] [WIP] Deprecation
<ekleog> ugh. so real code in nixpkgs (or not far) even depends on this behaviour. so even patching nix won't save me :(
<infinisil> (And see the comment on the argument too)
<infinisil> (Well this code is not in nixpkgs yet)
<ekleog> the world makes no sense :(
<ekleog> (sorry I'm just sulking)
<ekleog> that makes typechecking arguments to functions uselessly hard :(
<infinisil> Hmm
<infinisil> Another reason Nix isn't made for types :)
<ekleog> heh
<ekleog> another reason why nix makes it uselessly hard to add a decent typing system
<ekleog> (your use case could be covered by making it ? "don't use this value ever ever ever ever (c) infinisil", couldn't it?)
<infinisil> I guess, but that feels weird
<ekleog> well, if it could make the language a bit more sane it'd worth it imo :) (yeah, that's not gonna happen anyway :( )
<infinisil> > let foo = { a ? builtins.currentTime }@s: if a == builtins.currentTime then "a was passed" else "a was not passed"; in foo { a = 10; }
<{^_^}> "a was not passed"
<infinisil> > let foo = { a ? builtins.currentTime }@s: if a == builtins.currentTime then "a was passed" else "a was not passed"; in foo {}
<{^_^}> "a was passed"
<infinisil> :P
<infinisil> I guess builtins.currentTime could still just be the argument you pass though
<infinisil> > :v rand
<{^_^}> rand = next
<infinisil> > :v next
<{^_^}> next = s: lib.mod (1103515245 * s + 12345) 4294967296
<infinisil> > let foo = let thing = lib.mod (1103515245 * builtins.currentTime + 12345) 4294967296; in { a ? thing }@s: if a == thing then "a was passed" else "a was not passed"; in foo {}
<{^_^}> "a was passed"
clever has joined #nix-lang
<clever> infinisil: ok, what else can take an attrset and return it as a flat something
* infinisil is missing context
<clever> i'm trying to get nix to leak the order of keys in a set
<clever> nix-instantiate --eval -E 'builtins.trace (builtins.toJSON { b=1; a=2; }) (builtins.attrNames { b=1; a=2; })'
<clever> but attrNames sorts the result before returning it
<infinisil> Hmm..
<infinisil> builtins.toXML
<clever> nope
<ekleog> builtins.trace
<ekleog> (not really returning, but…)
<infinisil> Oh
<clever> the point of the above code, is to use trace to force the first set, creating b, then a, within the symbols list
<infinisil> > { ${builtins.trace "a" "a"} = "a"; ${builtins.trace "b" "b"} = "b"; }
<{^_^}> { a = "a"; b = "b"; }
<infinisil> Try that
<clever> which them means all future sets are in the b->a order
<infinisil> Oh wait, that's keys
<infinisil> Oh right
<clever> but nix is going out of its way to render all sets sorted by the keys as strings
<clever> oh, catAttrs
<clever> na, wont really work
<clever> oh, the order of f being called, with mapAttrs!
kalbasit[m] has joined #nix-lang
<infinisil> :O
<infinisil> You sure?
<clever> aha, i beat it!
<clever> nix-instantiate --eval -E 'builtins.trace (builtins.toJSON { a=1; b=2; }) (builtins.mapAttrs (n: v: builtins.trace "${n} ${toString v}" v) { a=1; b=2; })' --strict
<clever> nix-instantiate --eval -E 'builtins.trace (builtins.toJSON { b=1; a=2; }) (builtins.mapAttrs (n: v: builtins.trace "${n} ${toString v}" v) { a=1; b=2; })' --strict
<clever> the only difference between these, is the keys for the 1st trace
<clever> yet the order that mapAttrs runs the 2nd trace, differs
<clever> but you can only see that leak via the impurity that is stdout and trace
<clever> internally, nix hides this very well
<infinisil> Whoa nice
<clever> so the values of any set nix has previously parsed, will impact the order of keys within all future sets, and impact the order of mapAttrs
<infinisil> Ahh, so it first traces the toJSON, which fully evaluates the attrset, assigning numbers to names, then mapAttrs loops through those numbers in order?
<clever> yeah
<infinisil> builtins.attrNames instead of toJSON works too
<clever> yeah, anything that forces it in full
<clever> it may not even need a force, it might just be a side-effect of parsing
<clever> nix-instantiate --eval -E 'let ignored = { b=1; a=2; }; in (builtins.mapAttrs (n: v: builtins.trace "${n} ${toString v}" v) { a=1; b=2; })' --strict
<clever> yep, its a side-effect at parse time!
<infinisil> Hehe
<infinisil> nix-instantiate --eval -E 'builtins.mapAttrs builtins.trace { b = 1; a = 2; }' --strict
<clever> infinisil: i just had an idea
<clever> infinisil: your eval bot...
<infinisil> Could output traces, yeah
<clever> i could store secrets, in the order of keys i eval'd on it, in secret
<infinisil> Hehe
<clever> oh yeah, but without trace, i cant extract the answer
<infinisil> AHh yeah
<clever> enless, every value in the set throws?
<clever> and which one threw first, leaks
<infinisil> Hehehe
<infinisil> clever: But then you need 2^n many attrs for n bits
<infinisil> Heh yeah saw that before
<infinisil> > deepEval (builtins.mapAttrs (name: value: throw name) { a = 10; b = 10; })
<{^_^}> a
<infinisil> > deepEval (builtins.mapAttrs (name: value: throw name) { b = 10; a = 10; })
<{^_^}> a
<infinisil> > deepEval (builtins.mapAttrs (name: value: throw name) { someotherb = 10; someothera = 10; })
<{^_^}> someotherb
<infinisil> > deepEval (builtins.mapAttrs (name: value: throw name) { someothera = 10; someotherb = 10; })
<{^_^}> someothera
<infinisil> clever: :O
<infinisil> > secret = [ true true false ]
<{^_^}> secret defined
<infinisil> Eh, it doesn't really work well
<ekleog> now couple that with tryEval :D
<infinisil> ekleog: Unfortunately tryEval doesn't report the error
<infinisil> So there's no way to extract that
<infinisil> Related: nix#2421
<{^_^}> https://github.com/NixOS/nix/issues/2421 (by lheckemann, 4 weeks ago, open): Remove value for failed tryEval?
<ekleog> oh true
__monty__ has quit [Quit: leaving]