Nadrieril / dhall-rust

Maintainable configuration files, for Rust users
Other
303 stars 27 forks source link

Running functions? #208

Open L-as opened 3 years ago

L-as commented 3 years ago

I realize that the internal dhall crate is not stable, but I'd like to parse a function, then run it multiple times with different inputs. Is this possible? Thanks beforehand.

Nadrieril commented 3 years ago

The best would be if we could support that in serde_dhall. As far as I can see that's not possible sadly. (It might be possible with specialization maybe). The dhall crate does indeed know how to run functions, but it'll be a pain. You'll have to convert back and forth between Rust values and Dhall values manually, and that crate changes regularly :/ A workaround would be to take your inputs via environment variables. That way you can easily change the inputs from the Rust side, and you just run serde_dhall::from_file for each inputs. Not the best, but would that work for you?

L-as commented 3 years ago

I was thinking of running the function on every keypress, so yeah, it would technically work, but.. it's an ugly solution IMHO. The only values I'd pass back and forth would be nats, so data conversion wouldn't be a huge problem! Would this require so much code that I'd have to change it a lot on each revision of the crate?

basile-henry commented 3 years ago

This is not ideal but you can do the function application in Dhall:

fn run_dhall_fn(func: &str, input: u64) -> serde_dhall::Result<u64> {
    let input = serde_dhall::serialize(&input).to_string()?;

    serde_dhall::from_str(&format!("({}) {}", func, input)).parse()
}

fn main() {
    assert_eq!(run_dhall_fn("λ(x : Natural) -> x + 3", 5).unwrap(), 8);
}

If you need higher performance by only doing parsing, import resolution and typechecking once, then I think you'll have to use the less stable dhall crate itself. For most simple functions I expect the approach I shared to be good enough.

Nadrieril commented 3 years ago

@L-as I've written this test that does something like what you want. It shouldn't change too much, and definitely not every release. We'll keep this test updated, so this should help maintaining your code. Eventually we might commit to some stability, but we're not there yet.