One technique I often use to create a useful DomainSpecificLanguage/API is to take a sufficiently complex and representative example from the domain or problem and then "code" a solution in PseudoCode. The team then reworks the pseudo-code until it does a good job of representing the domain. Don't worry about implementation at this stage.
Once you have settled on this idealistic notation for the domain, then work backward to see how you can use languages and tools acceptable to your shop to make a reasonably close approximation of the ideal notation. If you have to bloat it up with language-specific artifacts to get it to match, then perhaps consider another production language.
Pseudo-coding helps you create DSLs and APIs that fit the domain well and are easy to read and change.
Too often we are tempted to think in terms of existing tools and specific technologies first. Doing idealistic free-form pseudo-coding first helps one see the problem in a different way. One can focus on representing the domain well instead of the nuts and bolts of existing software and tools. Sure, the nuts and bolts eventually will have to come into play, but don't let them limit your thinking at the early stages.
Without worrying about implementation, consider all the following for each given item:
Why that's... That's... REASONABLE! It even borders on insightful.
Who are you and what have you done with the real Top?
He flipped his top.
CRUD Example
I needed to create a set of reports that had a spreadsheet-like look in which only some of the cell borders were visible, some with double lines. The output was to be HTML + CSS, but it was too intricate to use HTML tables directly. Before I actually coded it, I needed some kind of concise report notation for this. I eventually settled on something like this:
cell(<value>, <span>, <formatType>, <borders>, <optionalParameters>)Examples:
cell(myVar, 2, "int", "NesW", "(bold)(shaded)"); or cell(myVar, 2, "int", "NesW", bold=true, shaded=true); // if named params are supported newRow(2); // start a new row, with 2 row spaces (blank lines) above it cell(myVar, 1, "text", ""); // no borders cell(myVar, 1, "text", "n"); // single-thick top (north) borderThe parameters are as follows:
Also, "newRow()" automatically "closed" any prior row such that I didn't need to specify nesting. A "startReport()" and "endReport()" would handle the first and last.
--top
Hmm. This looks like a really good place to use a commercial report generator, top. The use of a method call with parameters in a fixed order (and some of them optional) makes the table description code just as impenetrable as any C/C++ program with method calls to stuff nobody knows anything about. If you were using some sort of objectified report elements with attributes set separately then the code could read much easier, such as the following:
Cell First, Second, Third, Something; First.Value = SomeValue; First.RowSpan = 2; First.FormatType = Integer; First.TopBorder = BoldDouble; First.RightBorder = Single; ...I can see that this starts to look a lot like CSS, but at least anybody can see what the characteristics of the cells are supposed to be just by looking at the names of the attributes and the meaningful values given to them.
Of course, this also makes the description very verbose. However, it would be a lot easier to maintain for the casual maintenance guy who only comes along and changes the report format once a month or so. Eh?
I don't know if I agree. Even if it's easier to initially read, it may be harder to grok where and what it's actually impacting because it's all stretched out. My version is a little bit more WYSIWYG. Easy to figure out interface-wise and easy to use may be at conflict here. But then again, everybody's WetWare is different.
I'd also consider a key-word-parameter based interface. But, I generally like the first few parameters to line up like a table (TableOrientedProgramming left-overs?) so that one can read and compare them almost like they were in a table. Then the highly variable parameters on the right-ish side would be key-word parameters. Some nice languages allow one to use either keywords or position for a given call. Thus, if a bunch of calls appear together, then the confusion of being positional (unnamed) is not as costly because we only look up their meaning once and then know it for the entire page (or comment them on the top, like column headers), and have the more compact style. But if the call is isolated, then using the key-word style improves readability. Thus, if you are using a flexible language, an isolated call would have the parameter names spelled out, but when used in bunches, like above, we can use more of the positional style to keep the calls more concise and table-like.
As far as commercial report generators, I haven't seen one that handles heavily "tweaked" reports. If it's a simple grid, fine, but not nitty gritty blocks that don't follow a clean, regular pattern. They are usually plagued by the EightyTwentyRule. -t
A commercial report-writer was not in the cards. It was not in the contract budget. I did suggest it though. -t