Hacker News new | past | comments | ask | show | jobs | submit login

It all gets more complicated when you want to pass more than one secret parameter, or the function already returns a Secret - now you need a monad. The key feature seems to be that the code does not need 'map' or anything, the secrecy flag is propagated regardless.



> now you need a Monad

"need a Monad" sounds scary but in practice it looks like this

    impl<T> Secret<T> {
        pub fn map<U>(&self, func: impl FnOnce(&T) -> U) -> Secret<U> {
            Secret(func(&self.0))
        }

        pub fn flat_map<U>(&self, func: impl FnOnce(&T) -> Secret<U>) -> Secret<U> {
            func(&self.0)
        }
    }
If you need an escape hatch for something more complicated, you could provide an api to that

    impl<T> Secret<T> {
        pub unsafe fn reveal(&self) -> &T {
            &self.0
        }
    }


My point, which I didn’t express well there, was about the call side: How do you call

    func(param1: A, param2: B) -> C
with both parameters being secrets (secret1: Secret<A>, secret2: Secret<B>)? In Rust, it‘s

    flat_map(secret1, |param1|
      map(secret2, |param2|
        func(param1, param2)
      )
    )
or with do_notation at least a bit cleaner

    do! {
      param1 <- secret1;
      param2 <- secret2;
      Secret(func(param1, param2));
    }
whereas Rune manages it with

    func(secret1, secret2)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: