5 ms·
I often find myself yearning for a Rust REPL. I wonder if it'd be possible to run the rust compiler to lower the code down to MIR, and then run that in the Miri
by roblabla 8y ago
I often find myself yearning for a Rust REPL. I wonder if it'd be possible to run the rust compiler to lower the code down to MIR, and then run that in the Miri interpreter?
- navaati 8y agoI think the problem is not really evaluating Rust code on the fly: you could just as well compile it on the fly and execute is, this is what the Haskell interpreter ghci does. The difficulty is more in defining what it means to enter code one line at a time, what about context, scope, lifetimes, all these stuff. If a more knowledgeable Rust team member can confirm…
- richardwhiuk 8y agoI think some of the typing would be problematic, as it allows action at a distance. e.g. fn bar(i : &u16) { i + 1; } let a = 8; // a is a u8. bar(&a); // Now a needs to be a u16, // but we executed the line of code // above, which forced it to be u8. // Is this a type error? You can probably solve this, by requiring all blocks of code to be executed repl style to be standalone. i.e. the above code is entered as: fn bar(i : &u16) { i + 1; } ## Execution happens in the REPL { let a = 8; bar(&a); } ## Execution happens in the REPL. And make the far above give "a not defined in this scope"
- steveklabnik 8y ago(small note, a would be an i32 here, not a u8. your point stands though)
- gpm 8y agoI think you solve this by just giving an error In [0] fn bar(i: &u16) { i + 1 } In [1] let a = 8; // a is a i32. In [2] bar(&a) Out[2] Type error: a is a i32 and it needs to be a u16 In [3] let a: u16 = 8; // The original a is shadowed by the new a, the new a is a u16 In [4] bar(&a) Out[4] 9 Or a similar situation where there isn't enough information to infer a type In [0] let x = Vec::new(); Out[0] Type error: Need to know the type of x In [1] let x: Vec<bool> = Vec::new(); In [2] x.push(true); // Note that if we had entered this at the same tiem as Vec::new() the type could have been inferred.
- richardwhiuk 8y agoThat forces you to write very unnatural Rust - it makes it a much clunkier language.
- epage 8y agoThe Playground [0] and cargo-script [1] are the best options atm. In some respects, I think I prefer these. The only downside is the lack of introspection which is diminished by the use of static typing. [0] https://play.rust-lang.org/ https://play.rust-lang.org/ [1] https://github.com/DanielKeep/cargo-script https://github.com/DanielKeep/cargo-script
- richardwhiuk 8y agoIntrospection in the Playground is solvable with two things, a) everything defining debug, and b) `let _ : () = a; ` forcing Rust to tell you what type it's inferred.
- shepmaster 8y agoYou might be interested in issue #511: Building a REPL on top of miri [1] If you just want to get the MIR, you can do that today. In the playground, expand the "Run" menu and select "MIR". [1]: https://github.com/rust-lang/miri/issues/511 https://github.com/rust-lang/miri/issues/511
- mamcx 8y agoRelated is how use rust "as a library". I wish I could "compiler to rust": https://internals.rust-lang.org/t/pre-rfc-first-class-support-for-compile-to-rust-languages/7610 https://internals.rust-lang.org/t/pre-rfc-first-class-suppor...
- eximius 8y agoIt'd probably work best in a 'notebook' format. Take something like Jupyter Notebooks, throw a rust backend on it with each cell being a compilation unit... either throw them all back into a global scope or make each cell a module, I'm not sure. But repls make sense for python or something where you can realistically do line-by-line programming. Rust... I very frequently want to have an expression extend across multiple lines or define structures, etc, that a notebook just makes more sense.