colemickens has quit [Quit: Bridge terminating on SIGTERM]
jtojnar has quit [Quit: Bridge terminating on SIGTERM]
JJJollyjim has quit [Quit: Bridge terminating on SIGTERM]
l33[m] has quit [Quit: Bridge terminating on SIGTERM]
siraben has quit [Quit: Bridge terminating on SIGTERM]
siraben has joined #nix-lang
colemickens has joined #nix-lang
l33[m] has joined #nix-lang
JJJollyjim has joined #nix-lang
jtojnar has joined #nix-lang
mvnetbiz_99 has joined #nix-lang
Dotz0cat has quit [Ping timeout: 272 seconds]
Dotz0cat has joined #nix-lang
<infinisil>
Idea: Add an `unsafe { ... }` scopey thing to Nix
<infinisil>
Only within such blocks you can use unsafe (aka impure) operations like `builtins.currentTime`, `builtins.unsafeGetAttrPos`
<infinisil>
And these unsafe blocks can only be used for things like `builtins.trace <unsafe block>` or `throw <unsafe block>`
<infinisil>
So only for things that can't influence evaluation
<infinisil>
I guess more generally, a value would be "tainted" by an unsafe block, and tainted values could only be used with builtins.trace/throw
<infinisil>
This would only be enforced in --pure-eval mode though
<niksnut>
sounds expensive thought, since every value would need a tainted flag
<niksnut>
-t
<simpson>
infinisil: Strongly recommend that, instead, you have unsafe *objects*; pass in objects like `unsafeBuiltins` (but only when a --unsafe-eval flag is added) and call `unsafeBuiltins.unsafeCurrentTime`, etc.
<simpson>
The advantage is that this can be made capability-secure. It's still reckless though.
<infinisil>
niksnut: Hm yeah, maybe could abuse the last bits of pointers though :P
<infinisil>
simpson: Or maybe `builtins.unsafe.currentTime`, where `builtins.unsafe` only exists with `--unsafe-eval`
<infinisil>
(so we don't need another global symbol)
<simpson>
The entrypoint declares which unsafe objects it intends to use, and the caller decides which objects will implement those capabilities.
<infinisil>
Oh this is your Monte language?
<simpson>
Crucially, the entrypoint can't tell whether e.g. m`Timer.unsafeNow()` really is a current timestamp, or just a cached timestamp that *looks* like the current time. Same with the rest of the environment.
<simpson>
Yes, this is Monte, which is designed to make this sort of thing very easy to read at a glance. But Nix independently has a lot of the same philosophy.
<simpson>
Not exactly because all roads lead to capabilities, but because Nix is purely functional, and pure lambda calculi are always cap-safe.
<simpson>
Think of lambda as not just the ultimate abstractor, but the ultimate parameterizer; if you want to split up a capability into pieces, then you can make one of them a value and one of them a function.
<infinisil>
Interesting
<simpson>
This is why unsafe-blocks are not a great design choice; if you want to parameterize some pure code on some potentially-unsafe behavior, then you can wrap the behavior into a value and pass the value as a parameter. Then the overall safety of the composed code *varies* with the parameter.
<qyliss>
simpson++
<{^_^}>
simpson's karma got increased to 41
<infinisil>
simpson: Hm, so you think if the `builtins.trace/throw` thing should work, that it should be something like `builtins.trace (unsafeBuiltins: toString unsafeBuiltins.currentTime)`?
<infinisil>
I can see how that makes more sense, but it's a bit too verbose and impractical
<simpson>
infinisil: The "oasis of side-effects" model is really useful for something like builtins.trace, yeah, but another possibility is to make traces have a timestamp by default! This is the case in E and Monte, because it was just too common otherwise.
<infinisil>
I guess that works with timestamps yeah, but e.g. builtins.unsafeGetAttrPos wouldn't work for this, and this would be nice to use for better error messages giving more position information
<infinisil>
Though I guess these use cases are fairly limited. Most Nix impurities are used to impact the evaluation
* simpson
pulls a JRE to check what E-on-Java does
<simpson>
infinisil: Here's E: https://bpa.st/DC4A and Monte: https://bpa.st/XYRQ E's includes timestamp, logger source, log level, and caller source span; Monte's includes timestamp and vat name.
<infinisil>
I see, yeah that's comparable to Nix's --show-trace (the backtrace at least)