Babel - Data transformations made easy

As I mentioned before, I’m working on a LiveBook example.

But beyond that I can only repeat what I wrote earlier:

Doing these non-trivial transformations with standard library mechanisms is feasible but if you don’t want to raise and instead collect errors and be able to explain them, it becomes very complex - and also very hard to read - very quickly.

Maybe the confusion stems from this?

Babel does not raise unless you call apply!/2 (which calls apply/2 under the hood and raises in case it returns an error). At no point during the transformation exceptions are involved. It’s all results that get accumulated.

Your example is actually a good one to compare against because it’s largely optimized for the happy path. Defaulting to nil values is not something that flies in production. Neither is using Map.fetch!/2 from my experience. Those are cases where gracefully handling errors is preferred. Babel is optimized for exactly this. That’s where most of the work is. But you get that for free.

A comparable solution would check at every step if an error occurs, collect it, and return the accumulated error. It would be able to explain why that step failed, what the step was, and what the input data was. That version of the code will be a lot more complex. Often enough code is written that only focuses on the happy path, which then becomes hard to debug when something does not work. I’d like to refer to the initial error handling example to point out how much information Babel provides in error cases. You could say that Babel not only transforms but also asserts on the expected data shape.

Ecto is excellent when you have control over the shape of the incoming data. If you don’t, you will have to write a non-trivial amount of code to transform the data into a shape ecto understands. If Ecto fits your use-case: great, use that. But Ecto and Babel do not cover the same use-cases.

1 Like