5 ms·
Ultimately we avoid that with a few specific things: 1. As sane config as possible. 2. ability to hook into functional processes and see what's going on 3. L
by zachdaniel 3y ago
Ultimately we avoid that with a few specific things:
1. As sane config as possible.
2. ability to hook into functional processes and see what's going on
3. Layered escape hatches. You can add functional hooks to actions, or you can use a manual action to take over the data layer interaction, or you can write a "generic action" which gives you even more control. The escape hatches are designed to allow as much customization without sacrificing capability as possible.
4. Ash isn't its own language/environment. It's just an Elixir library. If doing something with Ash is proving difficult for whatever reason, you can opt not to use it for that, and then you're back in Elixir-land in full control. Ash doesn't attempt to "own" the things you use it with (in fact we take extra care to be as compatible with other tools as we can. For example, each Ash resource is also an Ecto schema. In this way, Ash can handle the 90+% of your application that is typically table-stakes, and you can handle the rest.
Also, I liken declarative programming to sushi. There are a lot of people who don't like sushi, because they've only had bad sushi :)
- skybrian 3y agoThanks for explaining! Another approach that I think works well is exemplified by ‘make -n’ where it prints a script for what it would do in a particular situation. Make’s rules-based syntax has its advantages, but imperative scripts are also pretty easy to understand, so it’s nice to see a conversion from one to another. (To go deeper, though, you need to understand what the commands do.) I haven’t used it, but I believe the Cue language can generate JSON output, which would be another example of translating from a sophisticated config language to a simpler, more verbose one. (Though, again, you need to understand the code that ingests the configuration to go any deeper.)