infinisil has quit [Quit: Configuring ZNC, sorry for the joins/quits!]
infinisil has joined #nix-lang
<sphalerite>
why does tryEval have value if it's unsuccessful…
<sphalerite>
> tryEval = x: let r = builtins.tryEval x; in if r.success then r else { success = false; }
<{^_^}>
tryEval defined
<sphalerite>
> tryEval 5
<{^_^}>
{ success = true; value = 5; }
<sphalerite>
> tryEval (throw "nope")
<{^_^}>
{ success = <CODE>; }
<sphalerite>
> (tryEval 5).value or "failed"
<{^_^}>
5
<sphalerite>
> (tryEval (throw "nope")).value or "failed"
<{^_^}>
"failed"
<sphalerite>
it would be so much nicer to use
<MichaelRaskin>
Well, tryEval is older than the «or» syntax
<sphalerite>
even then
<sphalerite>
why have a value when nothing meaningful was obtained?
<MichaelRaskin>
builtins,tryEval (throw "nope")
<MichaelRaskin>
> builtins.tryEval (throw "nope")
<{^_^}>
{ success = false; value = false; }
<sphalerite>
seems very arbitrary to have it be false
<MichaelRaskin>
Hm. I probably looked at Common Lisp ignore-errors
<MichaelRaskin>
I don't remember why not null
<MichaelRaskin>
Maybe you could ask if anyone objects to removal of value on failure now that «or» exists
<sphalerite>
yeah I'll do that
<MichaelRaskin>
Realistically I implemented this because back in the day this seemed to be the most reasonable medium-term way to implement Hydra jobset generation in release.nix (walk everything, collect things with maintainers field and platforms field, not die on the first problem)
<infinisil>
sphalerite: I want tryEval to return the throw's message
<infinisil>
In case of failure
<sphalerite>
infinisil: I mentioned this in the issue too :)
<infinisil>
builtins.catch "no error" (e: "Got error: ${e}") => "no error"
<infinisil>
That looks a lot better than tryEval tbh
<MichaelRaskin>
I have a (possibly false) memory that returning too much details about the error was criticized for making non-specified order of dependency evaluation accessible in a succesful Nix expression evaluation
<infinisil>
order of dependency evaluation? What's that exactly?
<MichaelRaskin>
Well, evaluating something cn have ten simultaneous reasons to fail
<infinisil>
> (throw "fun") (throw "arg")
<{^_^}>
fun
<infinisil>
MichaelRaskin: You mean how e.g. this throws the first error instead of the second?
<MichaelRaskin>
For example
<MichaelRaskin>
Or you could have a list
<MichaelRaskin>
> [ (throw "fun") (throw "arg") ]
<{^_^}>
[ <CODE> <CODE> ]
<infinisil>
I don't think that would be a problem, it's how all languages work. And what gets evaluated first is fixed with Nix' laziness
<MichaelRaskin>
> __toString [ <CODE> <CODE> ]
<{^_^}>
undefined variable '__toString' at (string):194:1
<infinisil>
In Haskell terms, I think this would just make every value be `Either String a`, while `builtins.catch :: Either String a -> (String -> Either String a) -> Either String a`
<MichaelRaskin>
Well, it does create a risk of weird expressions that suddenly give a slightly different result on Nix update.
<infinisil>
Oh yeah, I guess in haskell you couldn't just `+` two `Either`s
<infinisil>
You'd need to use monady stuff to have them evaluate in order
<infinisil>
Still, I don't think that's a big problem, it could even be put into the semantics docs: "builtins.catch catches *any* error, without a fixed order"
<infinisil>
Where `pure (!x + !y)` == `do { _x <- x; _y <- y; pure x + y }`, it does these bindings from left to right, so it doesn't rely on evaluation order. This means that the left-most error will be the one to propagate
<sphalerite>
infinisil: or Control.Except? :)
<infinisil>
sphalerite: Yeah
<infinisil>
Let's add do notation to Nix!
<sphalerite>
let's make nix into a haskell library!
<MichaelRaskin>
Let's die heroically trying to clean out all the type ambiguities in Nixpkgs!
<sphalerite>
The ability to have type safety isn't an obligation to have type safety :D
<infinisil>
Hold on, why would evaluation order be impure
<infinisil>
MichaelRaskin: There's only a single way to evaluate expressions in lazy languages
<sphalerite>
infinisil: no there's not..? in (a + b) for instance, there's no reason for a to be forced before b or vice versa
<sphalerite>
infinisil: they could just as well be evaluated in parallel
<infinisil>
Nope
<infinisil>
(a + b) = (((+) a) b)
<sphalerite>
right but ((+) a) doesn't require a to be evaluated
<sphalerite>
because it's lazy.
<sphalerite>
:)
<infinisil>
Ah
<infinisil>
I guess it depends on the primops keeping the same order
<infinisil>
But assuming those are fixed, the evaluation order is always the same
<sphalerite>
but there's no reason for them to
<infinisil>
But there's also no reason for them not to
<sphalerite>
as I said, they could even be evaluated in parallel to potentially improve performance.
<sphalerite>
yes there is ^
<infinisil>
Oh
<infinisil>
I see, alright but then the result has to wait for both results anyways, at which point the error of the left one will probably be checked first
<MichaelRaskin>
infinisil: also, why the assumption that lazy = full-currying
<infinisil>
Eh not sure, but Nix works that way anyways
<infinisil>
I think
<infinisil>
Or not, I guess not with primops lol
<infinisil>
But anyways, I don't think it would be hard to guarantee a fixed evaluation order
<infinisil>
ANd I don't see any problems that could arrive from such a fixed order
<infinisil>
(I really thought I saw nix-instantiate --parse return something like `((__add a) b)` for `a + b`, but I guess it doesn't)