| 25 Oct 2025 |
Katalin 🔪 | yeah: https://wiki.haskell.org/$ | 13:44:36 |
KFears (burnt out) | So like foo bar (baz queux) is foo bar |> baz queux? | 13:45:11 |
KFears (burnt out) | But it only works with the last argument, because otherwise you still have to parenthesise? | 13:45:46 |
Katalin 🔪 | <|, but yeah | 13:46:18 |
Katalin 🔪 | adapting the example from the haskell wiki:
f <| g <| h x == f (g (h x))
f g h x == ((f g) h) x
| 13:47:57 |
emily | <| is also more "order-of-eval-correct" | 13:48:41 |
emily | (though (&) as flip ($) is also popular in Haskell – or was, back in my day…) | 13:48:52 |
emily | (I personally avoided using $ in Haskell for various reasons so I have little opinion on any of this other than to say what I'd really like in Nix is function composition operators) | 13:49:29 |
KFears (burnt out) | Interesting. Is it weird that I prefer parens? | 13:50:19 |
K900 | ~~lib.pipe~~ | 13:50:28 |
emily | parens can be ugly if you want something (x: …) (vs. something <| x: …) | 13:50:42 |
Katalin 🔪 | In reply to @emilazy:matrix.org parens can be ugly if you want something (x: …) (vs. something <| x: …) unfortunately the latter doesn’t actually parse right now :( | 13:51:05 |
Katalin 🔪 | I would really like that | 13:51:12 |
emily | in Haskell this often came up as
thingy = foopy $ do
…
as opposed to
thingy = foopy (do {
…
})
though they fixed it by just making foopy do work
| 13:51:27 |
KFears (burnt out) | They are somewhat ugly, but they are universal, unlike the backpipe which only works on the last argument | 13:51:33 |
emily | not sure if you could make f x: … work in Nix to mean f (x: …) | 13:51:36 |
emily | heh, in Haskell again a niche but existing opinion was that a $ b c $ d e should parse as a (b c) (d e) rather than a (b c (d e)), because you can achieve the latter as a . b c $ d e using the function composition operator | 13:53:06 |
emily | though of course Nix has no function composition operator so you'd have to turn it around into d e |> b c |> a | 13:53:28 |
@dawnofmidnight:catgirl.cloud | would need parens anyway for the body in any case that's not like… constant or the identity function, so i don't think it'd be particularly useful? | 13:53:27 |
emily | that is unfortunate and makes me think I'd never use <| | 13:53:46 |
emily | hm, why? you do have to decide how foo = f x: x + 2; parenthesizes, but f (x: x + 2) seems like almost invariably what you'd want in practice | 13:54:22 |
Katalin 🔪 | nix-repl> f <| x: x + 1
error: syntax error, expecting end of file
at «string»:1:7:
1| f <| x: x + 1
| ^
it seems like a bug to me
| 13:54:30 |
Katalin 🔪 | but who knows | 13:54:38 |
emily | in particular this would allow
stdenv.mkDerivation finalAttrs: {
…
}
| 13:54:40 |
emily | basically you would get trailing "block" syntax. not saying this is something that should be done, just you could do it, and it would make some things look a fair bit nicer | 13:55:14 |
emily | (though ofc the Nix grammar is cursed enough that it might expose other gremlins) | 13:56:01 |
@dawnofmidnight:catgirl.cloud | that's the case i was thinking of, (f x: x) + 2 is a perfectly interpretation. i suppose you could say it consumes as much as possible, but that is sort of contrary to the behavior of say, [ f x ] where you don't consume more (though whether this is analogous is debatatable). you can absolutely define it to be that, but i feel like it would break precedent? dunno | 13:56:32 |
Katalin 🔪 | In reply to @kfears:matrix.org They are somewhat ugly, but they are universal, unlike the backpipe which only works on the last argument sure, but often you do specifically end up with lots of long expression as specifically the last parameter | 13:56:43 |
Katalin 🔪 | In reply to @kfears:matrix.org They are somewhat ugly, but they are universal, unlike the backpipe which only works on the last argument * | 13:56:51 |
@dawnofmidnight:catgirl.cloud | ah right, i forgot that this would be unambiguous. blocks are compelling (though i personally don't think it justifies the whole thing) | 13:57:08 |