Browsing the archives for the DSL tag.

I’m using the wrong language.

work safe

A few years ago, we did some embedded control testing that got me seriously thinking about language. The system was specked out using signal flow diagrams, the kind I remember from digital signal processing in college. The code was white-boxed C poking and prodding at a lot of global variables. Our test tool let us define values in terms of other values, invoke the C code, then assert some values with our expected. Think of this as like using excel to model signal flow.

Here’s an example of a signal flow diagram from
Signal Flow Diagram

The signal flow diagrams used a lot of sub components, some that were deeply nested. Our test tool doesn’t have any abstraction; no functions, no macros, and no components. This lead to repetition in our test code. If I had three calls to a sub block, I would copy/paste/rename upwards of 60 lines of code for each block. Code reviews were important and kind of intense. We couldn’t stand the tool, but the tooling surrounding it was worth the hassle. We had code coverage, logging reports, and most importantly we had decision coverage.

But it still felt like I was programming in the wrong language. At that time in my life I tended to think, “I should be writing in Ruby.” But even that’s only part of the story.

What I wanted to do was model the diagrams more directly. I wanted to define a component, wire five of them together, define my input ranges, and make some assertions. I wanted my test code to feel like you were looking at a diagram. This would make the code easier to maintain, reduce duplication, and make it easier to review.

I sat down with Ruby’s mutable syntax and tried to whip up a model of a few representative diagrams. I couldn’t make it perfect, but I could hit the 80% mark and leave enough “bare metal” to work around for the last 20%. All it did was spit out the code I would have written by hand, but it was much easier to write in my little language. The best part is all our existing tools worked just the same.

test 10, "4 step floating average" do
  inputs :in => [0.0, 10.0, 13.0]
  inouts :delay_1 => [0.0, 10.0, 13.0],
         :delay_2 => [0.0, 10.0, 13.0],
         :delay_3 => [0.0, 10.0, 13.0]
  delay_1 = instance :delay, :delay_1_expected,
         :input => :in
  delay_2 = instance :delay, :delay_2_expected,
         :input => delay_1.output
  delay_3 = instance :delay, :delay_3_expected,
         :input => delay_2.output
  double :expected, "(in + delay_1'IN + delay_2'IN + delay_3'IN) / 4"
  assert :delay_1 , delay_1.output
  assert :delay_2 , delay_2.output
  assert :delay_3 , delay_3.output
  assert :answer, :expected

I am happy with the solution. Not because I get to write in Ruby, but because I can write the code that fits the solution. That’s when I started to really understand the power of language to clearly express the problem and solution at hand.

I’m presenting to IndyAlt.NET on Domain Specific Languages this week. This isn’t just programming language wankery, though I’ll admit that part is fun. It is about using the right tool for the job. I’m currently writing an application in C#. But the majority of my code should only superficially be called C#. I should bend C# to express the domain and let me program the solution, not the implementation.


I’m totally plugged in!

work safe

There are few things in life better than humus and pita chips.

There are few things in life are as insidiously addictive as brain-crack, the idea not executed. These ideas sit in your brain festering, growing malignantly, until there is no hope of you ever achieving them like the “perfect utopia” they have become.

I bring this up because I had 2 in particular that where starting to rattle around in my brain like horrid clattering moose (moose clatter, right?). I’m a junkie for computer languages, and when Rick Minerich mentioned Irony recently followed quickly by a project manager asking about writing a testing DSL, I started to feel that tumor grow in my delicate, delicious brains. I should write a language. Then it split in twain. There is no reason to have a programming language, even a DSL, without an editor that understands it. I’d need a Visual Studio plug in to make that work. And those are hard, right? Besides, I would want to do it right and reuse the parser built for the first to syntax highlight the second. Uh, oh. I now have an idea for the perfect DSL framework rattling around in my skull.

The problem is, I only have enough room in my brain for a handful of things at any given time. So, I took the weekend to clean house. The idea is not to get something perfect. I just want to get it done enough to say, “I did that.” And now I can get to sleep tonight. My DSL isn’t for supporting your important work, it is for proving I know how to do it.

First lesson learned: Irony has crappy and out of date documentation. Every example I’ve seen uses API calls no longer in the library. In addition, most focus on how cool the internal DSL Irony uses for creation of the language grammar. And it is cool. But some of us missed the last mile. I’m not going to solve that issue here. I did, however, post my weekend exploration to github. Enjoy!

Second lesson learned: VS 2010 isn’t that hard to extend, once you know where to look.

Third lesson learned (again): I can’t spell. I had set the file extension to “circles” when I was using a file called “circle”. That means my plugin wasn’t triggering Saturday, so I had a Ukulele break and came back to it this afternoon.

Fourth lesson learned: Visual Studio lies. It gave me an error when my extension crashed about ActivityLog.xml but I couldn’t find it. I had to enable -log at the command line for the extension. Then it was easy.

Fifth lesson learned: a full grammar sucks for syntax highlighting. Effective syntax highlighting requires robustness because it should work, not only on a full program, but on a program as it is being typed. See the screen shots to better understand.

An incomplete circle definition

Complete Circles Definition

I’m not “finishing” this project. It has done what it was meant to do, serve as a prof of concept sketch that I can refer to later. Enjoy!

No Comments

Irony and Circles

work safe

When I started my DSL talk for los officiea, I was looking around for neat DSL things to add when I found Irony.  I found it at a Lang.NET talk.  Then I wrote a small DSL to define some geometric circles.  So, here’s a quick rundown of how I made it happen.

Irony is used to define a parser.  Inside the parser’s constructor, we build the BNF tree that describes the grammar.  When that’s done, Irony will spit out an Abstract Syntax Tree (AST) that we can use for “real work”.  Let’s take a look at some of the grammar, before we see the Parser code.

program <- shape +

shape <- circle | polygon | rectangle

circle <- circle point radius number

point <- [ number , number ]

What this looks like is the program ‘circle [100, 150] radius 35’.  It gives me circle with a center and a radius.  What’s that look like in C#?  Or at least the circle bit?

Continue Reading »

1 Comment