← Back to context

Comment by gruseom

14 years ago

Hmm, good question. I'd say it's less true of bottom-up programming because there you're generalizing code you've already written. It's possible to get that wrong, i.e. introduce abstractions that capture what was there before but don't make it easier to write the program going forward, in which case the best thing to do is rip them out and replace them with their compiled equivalents until a better idea emerges. But it's all very incremental and the cost of getting any individual construct wrong is relatively low.

Classical DSLs are harder because of the D. You have to nail the domain/language fit or it's more trouble than it's worth. Even then you don't necessarily win enough to justify the cost: a specialized language needs to be significantly better than "just coding your domain model in your general-purpose language", which is a high bar. There isn't only the cognitive cost of learning a specialized language, there's the interoperability hit (can a general program call the DSL and vice versa), lack of tool support and so on. It doesn't make sense for most domains, especially business domains that don't lend themselves to technical notation.

The thing that bottom-up programming has taught me, not that I'm in any way sophisticated at it, is that good language constructs need to be an order of magnitude more lightweight than good application constructs. Application constructs are what you pack in your car for a road trip, language constructs are what you put in your backpack for a hike. Or another metaphor: application constructs are factory equipment, language constructs are hand tools - if you have to think about how to use it, it sucks. I find it's hard mentally to go back and forth between these two design levels. I'm spending a few days at the language level right now so these things are on my mind.