I think that wouldn't be too foreign to anybody who has worked for a while in Rust? It's definitely more compact and expressive than the Rust equivalent, though.
This doesn't look or feel all that different to me:
enum Expr {
Const(f64),
Var(String),
Sum(Box<Expr>, Box<Expr>),
Diff(Box<Expr>, Box<Expr>),
Prod(Box<Expr>, Box<Expr>),
Quot(Box<Expr>, Box<Expr>),
}
fn print_expr(exp: &Expr) {
fn open_paren(prec: i32, op_prec: i32) {
if prec > op_prec {
print!("(");
}
}
fn close_paren(prec: i32, op_prec: i32) {
if prec > op_prec {
print!(")");
}
}
fn print_rec(prec: i32, exp: &Expr) {
match exp {
Expr::Const(c) => print!("{}", c),
Expr::Var(v) => print!("{}", v),
Expr::Sum(f, g) => {
open_paren(prec, 0);
print_rec(0, f);
print!(" + ");
print_rec(0, g);
close_paren(prec, 0);
}
Expr::Diff(f, g) => {
open_paren(prec, 0);
print_rec(0, f);
print!(" - ");
print_rec(1, g);
close_paren(prec, 0);
}
Expr::Prod(f, g) => {
open_paren(prec, 2);
print_rec(2, f);
print!(" * ");
print_rec(2, g);
close_paren(prec, 2);
}
Expr::Quot(f, g) => {
open_paren(prec, 2);
print_rec(2, f);
print!(" / ");
print_rec(3, g);
close_paren(prec, 2);
}
}
}
print_rec(0, exp);
}