Monday, August 2, 2010

DSL's vs Functional Languages

Sometimes I struggle with the balancing point between Domain Specific Languages (DSLs) and functional programming. DSL's have a nebulous definition, which seems to depend on the context within which the language is being used. Functional languages are defined just as loosely, and what is and is not functional is a matter of great debate.

For my purposes, I will just define what I mean by a DSL and a functional language. What follows is not strictly THE definition of either of these things, but really, who cares.

A DSL is a language that hides a great deal of the inner workings from you in order to allow you to very succinctly and clearly specify something. In my mind, a DSL does a great deal of "magic" behind the scene to make programming very easy for you. Flavor wise, a DSL should allow you to specify a solution to a problem in the minimal (most terse) form. It should deal almost exclusively with pure business logic, as everything else is being handled "behind the scenes" by the DSL itself.

A functional language is a language that allows functions as first class objects. That allows lambdas and closures. Where functions are pure (side effect free). And, although not stricly true by definition, that does not allow modification of state without safety (that was some hand waving). Functional approaches like to keep the data visible, most every change in the program should be the result of a function call. Ideally, I can see the value passed to a function, and I can see the result returned from a function. This can be extremely useful in development, as it makes it trivially easy to determine where a error occurred: simply look for where the value was first incorrect, and determine where said value came from. The function that generated the first in error value is guaranteed to contain the code that generated the error, assuming the functions are pure.

Sometimes though I feel a domain specific approach and a functional approach are somewhat at odds. You see, the functional approach wants to keep everything as a immutable and visible data structure. Because a functional language is immutable and because functions themselves are side effect free,  one does not spend much time "hiding" details. Because of these constraints however, everything that the function needs to have to generate its result MUST be passed in as a argument. This can often result in passing a great deal of information to a function, which is verbose. DSL's, in my mind, are almost the opposite. A DSL attempts to hide a great deal of information that it silently provides to the function.

As an example, let us say that I had a function that required 10 argument when it was called (This would be a good example of a "bad code smell", but let us ignore that for now). With a functional design, you just pass in all 10 arguments. With a DSL design, you only pass in 2 and the DSL passes in the other 8. This isn't really how DSL's work, but I think it illustrates my point. The advantage to the functional is that you get to see everything that is going into the function through the arguments. The advantage to the DSL is that it is extremely terse. The simple difference is the number of arguments, but the implications of this example somewhat illustrates the difference in philosophies between these two approaches.

How can these two design approaches meet? A functional approach is attempting to make the "state" of the program viewable at all levels, no data should be hidden. A DSL approach is attempting to "hide" as much of the program as possible, such that the programmer only needs specify the actual business logic to get a working program. I am not saying that this is a insurmountable problem, simply that it is something I have been thinking of lately. How can I combine the power of a functional language with the terseness and specificity of a DSL?

No comments:

Post a Comment