Understanding Domain Specific Languages as Jargon

March 5, 2007 - 4 minute read -
software-development dsl

Domain Specific Languages (DSLs) are the idea of creating syntaxes that model a very specific problem domain. Domain Specific Languages are not a new concept. Some people call them 'little languages'. The Unix world has a bunch of little languages. Grep, awk, sed, lex, and yacc all exhibit features of these domain specific languages. They are little tools that do one thing well. In these cases they are often highly encoded and not in natural language of any sort. Modern domain specific languages should aim to be humane and literate in the language of the user.

Domain Specific Languages should be expressed in the language of the problem being solved. They are a higher level of abstraction than for loops and object instantiation. They are at the level of abstraction of the problem space. Neal Ford uses the example of "venti nonfat decaf whip latte". What am I talking about if I use those terms? If you guessed coffee, then you know the Jargon of one coffee chain out there. The person listening to the order understands that you are ordering a decaf coffee drink of a certain size, with non-fat milk and whipped cream. There is a lot of shared context in the Jargon of the coffee drinker and the coffee order taker. This shared context sets the stage for a rich conversation without a lot of unnecessary noise. This is true of all Jargon.

# CoffeeDSL.rb
# This is the input from the user, likely read from a file
# or input through a user interface of some sort
CoffeeInput = "venti nonfat decaf whip latte"
class Coffee
    def method_missing(symbol)
        name = symbol.to_s
        if %w(venti grande).include?(name)
            @size = name
        elsif %w(whip nowhip).include?(name)
            @whip = 'whip'.eql?(name)
        elsif %w(caf decaf halfcaf).include?(name)
            @caf = name
        elsif %w(regular latte cappachino).include?(name)
            @type = name
        elsif %w(milk nonfat).include?(name)
            @milk = name
        else
            raise ArgumentError, "Unknown coffee informantion: #{name}."
        end
    end
    def order
        params = ''
        params += @milk + ' ' if @milk
        params += @caf + ' ' if @caf
        params +=  'whip ' if @whip
        print "Ordering coffee: #{@size} #{params}#{@type}\n"
    end
    def load
        # turn one line into multi-line "method calls"
        cleaned = CoffeeInput.gsub(/\s+/, "\n")
        self.instance_eval(cleaned)
    end
end
# this is your code which loads the DSL input and executes it
coffee = Coffee.new
coffee.load       # load the user input
coffee.order      # submit the order

Jargon is the terminology of a specific proffession or group. Does your user community or problem space have a vocabulary? Can they express the things they want out of a system using that vocabulary or Jargon? If so, there is a very real possibility that you could utilize a DSL to solve some set of problems for those users.

What about field validation?

# ValidationDSL.rb
# Input from the user that would be read in
Input = <<EOF
min_length  2
max_length 5
EOF
class Module
    def dsl_accessor(symbol)
        define_method("#{symbol}") do |v|
            instance_eval
            %{
                 @#{symbol} = v
            }
        end
    end
end
class ValidateDSL
    dsl_accessor :max_length
    dsl_accessor :min_length
    def validate(field)
        if @max_length and field.length > @max_length
            return false
        end
        if @min_length and field.length < @min_length
            return false
        end
        return true
    end
    def load
        self.instance_eval(Input)
    end
end
val = ValidateDSL.new
val.load
print val.validate('foo')
print "\n"
print val.validate('')
print "\n"
print val.validate('abbbbbbbbbbbbbbbbbbbbbb')
print "\n"

How does your user community talk about a problem? Can they easily express what they intend with simple Jargon that they already know? Is that more natural for a power user than some complicated UI with buttons and checkboxes? Then you might have a good place to use a DSL.