Hacker News new | ask | show | jobs
by pjc50 3615 days ago
So how does one avoid this trap?

I've occasionally thought of using a DSL for some business logic, presumably the best way is to at least use an existing language (like Tcl) and provide business-specific verbs in it?

2 comments

Don't build a DSL for a production system, period. Production quality DSLs are for academics and/or staff engineers that have enough time and resources to build and maintain them.

I don't know about you, but I have a constant backlog of features with tons of interesting problems to solve. There are places where I could build a DSL, but I am not going to because I would inevitably build something hacky and brittle that is impossible to understand and maintain (like JDSL).

I can't build new features, and increase the value of the system if my DSL is constantly breaking the system.

So don't do it. There is plenty of functionality on the .NET and Ruby platforms for me to model the concepts and objects in the domain without the need for a DSL.

Oh, this reminds me.

I once worked for a company that used RDF for all configuration and scripting for one of its main applications.

Instead of using one of the standard methods of encoding RDF (turtle, XML, etc.) our main architect wrote his own. Specifically, he wrote an encoding based on Google Sheets. The triples were the row header, the column header, and the cell value. There were two special tables; one containing namespace aliases and one containing an index of all the tables in the spreadsheet.

To deploy, you published a Google Sheet to the web, copied the sheet key, and pasted it into a variable in the Java code's main() function (and we had a few different main classes for a few different deployment types).

Later on, he added support for encoding RDF in XLSX spreadsheets so we don't need an Internet connection to launch the app.

Let's just say that architect and I didn't get along (and he didn't get along with a good chunk of the devs either; multiple people I worked very well with quit during my time at that company largely because they couldn't get along with him).

If you want to see it, the code is open-source (some of their content is proprietary, but there's an open-source RDF store in the public repos that has the proprietary stuff removed and replaced with demo content). It forms part of the appdapter project on Assembla [0] (but only part of it; there's other random stuff in appdapter too), and there are some sample main() functions in the friendularity project on Asssembla [1] (friendularity was our repository of open-source main classes; they mostly just import stuff from other open-source projects and wrap it in a main()). Honestly, though, I didn't touch the appdapter part of the codebase when I worked there, and it's been a couple of years since I've worked there, so I don't think I can help much with running it. I think org.friendularity.bundle.demo.ccmio (or maybe org.friendularity.bundle.launcher.oglweb) is the relevant main project, but I don't remember too well, and I think some things have been refactored since we left.

[0] https://app.assembla.com/spaces/appdapter/subversion/source

[1] https://app.assembla.com/spaces/friendularity/subversion/sou...

While that is probably a bad idea... it does give me a potentially good idea... using google sheets for internationalization string management... so you don't have to build a custom UI.

two-column sheets.. first sheet is "default", sheet name == lang_location and overrides... column 1, except first row, is the key, column 2 is the localized value, column 3+ unused, but can provide more context information.

It really depends. In this example they used JSON to basically create a new programming language. I know a couple of projects where a DSL is used for declarative parts of the project. For example in one projects they took one or more inputs from sensor values, applied a calculation and created a new virtual sensor output. For such highly specialized tasks a DSL can be the better option.
You could try sketching out on paper or a whiteboard what control structures you would need to pull off the DSL, and then exposing those control structures as utility classes instead of a DSL.

For example, if you are building up a queue of commands to be run in sequence with a bit of preprocessing, you might create a class that exposes: `addStep`, `preprocess`, and `run`.

At least for me, the impulse to create a DSL was always a secret desire to hide implementation details from readers so that they can see the intent of the code more clearly. Really, those implementation details are critical for maintainers to understand. Otherwise a DSL's magic is likely to hurt a maintainer when their expectations are off.