upvote
You're absolutely right that this approach encodes domain complexity in the data, and I agree that's not the magic sauce per se.

Honestly, it's just really hard to convey how simple code can be. Imagine a nerual net inference engine in 30 straightforward lines of code and no libraries! [0] On one page you really can read off the overall algorithm, tradeoffs made, algorithmic complexity, and intended highlights.

Abstractions encourage hiding of information whereas subordination encourages keeping it implicit.

Are you familiar with Observability 2 and wide events? In this data-first model we effectively encode all program behavior into a queryable data structure. I'll often breakpoint something I'm working on and iteratively drill down into the data to get to the root of a problem. That's just so friggin cool, IMHO.

Abstraction almost always manages complexity by introducing some control flow barrier like an API call. Observing said control flow is a lot more indirect, though, either via statistical sampling or in flight observation. In contrast, imagine if you could simply throw SQL queries at your application and you get an idea of what I'm stumbling to convey here.

[0]:https://doi.org/10.1145/3589246.3595371

reply
> But in doing that, aren't you simply moving the complexity of the abstractions from the functions code into the data structure?

The core idea behind most of functional programming and APL is that data don't change. Policies do. So you design a set of primitives that can represent any data types by combination, then build a standard library that combine and split them, as well as transform them into each other. Then you have everything you need for expressing policies.

Let's take music notation as an analogy. You only need the staff for pitch and the note-head for duration. And with those (plus other extra symbols), you can note down most music. You can move higher up with chords, but you don't really need to go much higher than that.

Data are always external to the business domains. Only policies are internal. Those policies need semantics on data, so we have additional policies that takes rough data and transform them into meaningful one. What Java, C#, and other do is fixing those semantics in the code and have the code revolve around them. But those labels are in fact transient in either the short or long term. What you really need is a good way to write policies and reasons about them.

I like Go because it lets you define data semantics well, but don't confine your policies.

> Someone reading the program for the same time will have just the same difficulties understanding what the code does, not in terms of primitives, but in terms of business domain meanings.

That's what naming and namespacing is there for. Also docstrings.

reply