4 ms·
Duplication can sometimes be useful, for instance if you have many small variations on a central process. Trying to make one process with all the edge cases ba
by CuriouslyC 3y ago
Duplication can sometimes be useful, for instance if you have many small variations on a central process. Trying to make one process with all the edge cases baked in leads to overly-complex, hard to reason about, expensive software.
In my experience, the right way to handle this sort of situation is to create a functional mini-DSL for the process that handles all the implementation details, then create a "default" process which serves as a template. If a process needs slightly different logic, just copy the template, update the DSL to support any new logic, and update the template with the new DSL statements. This approach lets you give semantic meaning to implementation details, and you can see where all the different custom logic is at a glace by looking at all the template copies. As long as the template is only calling out to DSL actions with no internal logic of its own and process flow is correctly encapsulated in the DSL, you should never need to update templates to change behavior, only update the DSL.
- tracker1 3y agoThis is generally my approach to data ingress/egress (ETL)... I'd rather have a hundred similar, small scripts for each data source than try to create one complex (monstrosity) application to handle them all.
- crazygringo 3y ago> is to create a functional mini-DSL Exactly. Is there a formal term for this? Instead of one gigantic function with 50 parameters, you have 100 "template" functions, that all make use 60 different "helper" functions (what you're calling the DSL). Instead of castles-of-logic abstraction, it's nuts-and-bolts or grass-roots abstractions. I've never come across a name for this development style. But it generally works extremely well when building processes for tens/hundreds of data formats or customers or what have you.
- consilient 3y ago> I've never come across a name for this development style. Libraries designed like this are sometimes called "combinator libraries".
- code_biologist 3y agoEmbedded DSLs is the term I’ve seen in the Haskell, Scheme and Ruby communities.
- fiddlerwoaroof 3y agoThis sounds like what lispers call something like “language driven design” or “growing a language”
- Kalabasa 3y agoBuilder pattern is a similar concept
- augustk 3y agoDSL = Domain-specific language (I guess). Always a good idea to expand an abbreviation the first time it's used.
- amalcon 3y agoThis way of doing things (which I agree is often the correct way) is the reason for Greenspun's Tenth Rule: https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule Though it's less true today and in languages that are not C or Fortran. Even something like C++ or Java has the template method pattern, which gets you 80% of the way there. Dynamic languages like Python or Ruby tend to have pretty reasonable facilities for building DSLs, as do more modern languages like Scala and Rust.
- kiitos 3y agoSo, to maintain your project, it's not sufficient for me to know language X -- I also have to learn a bunch of domain-specific sub-languages, which any developer on the project may have implemented in response to an arbitrary problem, which almost certainly has no kind of formal specification or stability guarantee, and which can change over time in any way without warning? No sir.
- CuriouslyC 3y ago"So, to maintain your project, it's not sufficient for me to know language X -- I also have to learn a bunch of functions, and understand the business processes that are used to create the abstractions, and trust code from my coworkers with just unit tests and type checking? No sir."
- kiitos 3y agoIt seems like you're equivocating language-level concepts like syntax, semantics, grammar, etc. with program-level concepts like types, functions, names, etc. But these are two categorically different things.