From C# to Rust: Porting MathFlow to Create MathCore – A Symbolic Math Library Journey



  var expr = MathExpression
      .Parse("x^2 + 2*x + 1");

  var derivative = expr
      .Differentiate("x");

  var result = expr
      .Evaluate(new  x = 5 );

  let expr = MathCore::parse(
      "x^2 + 2*x + 1"
  )?;

  let derivative = MathCore::differentiate(
      &expr, "x"
  )?;

  let result = math.calculate(
      &expr, &[("x", 5.0)]
  )?;

⚡ Performance Results

I was shocked by these numbers:

| Operation | C# (MathFlow) | Rust (MathCore) | Difference |
|——————|—————|—————–|—————-|
| Parse Expression | 245 µs | 89 µs | 2.7x faster ✨ |
| Differentiate | 1,230 µs | 456 µs | 2.7x faster ✨ |
| Solve Equation | 890 µs | 234 µs | 3.8x faster 🚀 |
| Memory Usage | 847 MB | 124 MB | 6.8x less 🎯 |


💡 Key Differences I Discovered

1️⃣ Error Handling

  C# Way (Exceptions):
  try 
      var result = MathExpression.Parse("invalid");
   catch (ParseException e) 
      Console.WriteLine($"Oops: e.Message");
  

  Rust Way (Result Type):
  match MathCore::parse("invalid") 
      Ok(expr) => println!("Success!"),
      Err(e) => println!("Oops: ", e),
  

💭 Insight: Rust forces you to handle errors. No more surprise crashes in production!


2️⃣ Memory Management

C#:

  • ✅ Garbage collector handles everything
  • ❌ Random GC pauses
  • ❌ Unpredictable performance

Rust:

  • ✅ Predictable performance
  • ✅ No GC pauses
  • ❌ Must think about ownership

3️⃣ Real-World Example

Let’s solve a physics problem – projectile motion with air resistance:


  // Calculate trajectory
  var equation = @"
      y = v0*sin(θ)*t - 
          0.5*g*t^2
  ";

  var solver = new MathEngine();
  var trajectory = solver
      .Parse(equation)
      .Substitute(new 
          v0 = 100,
          θ = Math.PI/4,
          g = 9.81
      );

  // Calculate trajectory
  let equation = "
      y = v0*sin(θ)*t - 
          0.5*g*t^2
  ";

  let math = MathCore::new();
  let trajectory = math
      .calculate(equation, &[
          ("v0", 100.0),
          ("θ", PI/4.0),
          ("g", 9.81),
      ])?;

🎨 Architecture Evolution

From OOP to Functional

  C# (Object-Oriented):
  public abstract class Expression 
      public abstract double Evaluate();
  

  public class AddExpr : Expression 
      private Expression left, right;

      public override double Evaluate() 
          return left.Evaluate() + right.Evaluate();
      
  

  Rust (Algebraic Data Types):
  enum Expr 
      Number(f64),
      Add(Box<Expr>, Box<Expr>),
  

  fn evaluate(expr: &Expr) -> f64 
      match expr 
          Expr::Number(n) => *n,
          Expr::Add(l, r) => evaluate(l) + evaluate(r),
      
  

🎯 Why this matters: Pattern matching eliminated entire class hierarchies!


🚀 Cool Features in Both

Features Comparison

| Feature | MathFlow (C#) | MathCore (Rust) |
|————————–|—————|—————–|
| Symbolic Differentiation | ✅ | ✅ |
| Equation Solving | ✅ | ✅ |
| Matrix Operations | ✅ | ✅ |
| Complex Numbers | ✅ | ✅ |
| Arbitrary Precision | ✅ | ✅ |
| Parallel Computation | ✅ Tasks | ✅ Rayon |
| WASM Support | ⏳ Coming | ✅ Ready |
| FFT | ✅ | ✅ |


📦 Try Them Out!

For .NET Developers:

dotnet add package MathFlow

  using MathFlow;

  var math = new MathEngine();
  var derivative = math.Differentiate("sin(x^2)", "x");
  Console.WriteLine(derivative); // Output: 2*x*cos(x^2)

For Rust Developers:

cargo add mathcore

  use mathcore::MathCore;

  fn main() 
      let derivative = MathCore::differentiate("sin(x^2)", "x").unwrap();
      println!("", derivative); // Output: 2*x*cos(x^2)
  

🤔 Which Should You Use?

Choose MathFlow (C#) if you:

  • 🔷 Are building .NET applications
  • 🔷 Use Unity for game development
  • 🔷 Want fastest development time
  • 🔷 Prefer familiar OOP patterns

Choose MathCore (Rust) if you:

  • 🦀 Need maximum performance
  • 🦀 Want to compile to WASM
  • 🦀 Build system-level tools
  • 🦀 Care about memory efficiency

📈 What I Learned

  1. Rust’s ownership model prevents entire categories of bugs
  2. Pattern matching can replace complex OOP hierarchies
  3. Zero-cost abstractions are real – high-level Rust code is FAST
  4. Both languages have their sweet spots

🔗 Links & Resources

MathFlow (C#)

https://github.com/Nonanti/MathFlow
https://nuget.org/packages/MathFlow

MathCore (Rust)

https://github.com/Nonanti/mathcore
https://crates.io/crates/mathcore
https://docs.rs/mathcore


💬 Let’s Discuss!

Have you ported a project between languages? What was your experience?

Drop a comment below! 👇


If you found this helpful, consider giving the repos a ⭐!

Happy coding! 🚀



Source link