One of the things that bother me is that it is very easy to loose overview in large wired structures and I think DSL’s can limit the distance between specification and implementation. Example of something set up with a very low abstraction in Spring:
<bean id="fileWritingProcess" class="com.xebia.clustering.processes.FileWritingProcess"/> <bean id="resequenceProcess" class="org.codehaus.prometheus.processors.ResequenceProcess"/> <bean id="fileWritingProcessor" class="org.codehaus.prometheus.processors.standardprocessor.StandardProcessor"> <constructor-arg index="0" type="org.codehaus.prometheus.channels.InputChannel" ref="fileWritingProcessor-input"/> <constructor-arg index="1"> <list> <ref bean="resequenceProcess"/> <ref bean="fileWritingProcess"/> </list> </constructor-arg> </bean> <bean id="fileWritingProcessorRepeater" class="org.codehaus.prometheus.repeater.ThreadPoolRepeater" init-method="start" destroy-method="shutdown"> <constructor-arg index="0"> <bean class="org.codehaus.prometheus.processors.ProcessorRepeatable"> <constructor-arg ref="fileWritingProcessor"/> </bean> </constructor-arg> <property name="exceptionHandler"> <bean class="org.codehaus.prometheus.exceptionhandler.Log4JExceptionHandler"/> </property> <property name="shutdownAfterFalse" value="true"/> </bean>
And this is only 1/4 of the XML configuration.
Or now written in a DSL in Groovy (I’m still playing with the concepts and Groovy, so it could be that the syntax isn’t correct).
def piped = environment{ queues{ queue(name:'queue1'), queue(name:'queue2'), queue(name:'queue3') } pipeline{ [parserprocess, queue1, parallel(threadcount:10){fibonacciprocess}, queue2, parallel(threadcount:10){piprocess}, queue3, [resequenceprocess,filewritingprocess]] } }
I think most can imagine what the last script is doing without knowing anything of the application. That is the power of a DSL.
or semantic closures ?