DSL question -- was: New slogan for haskell.org

Thanks for the explanation on DSL. It helped me understand how Haskell
works compared to other popular languages out there. It is a
programming methodology change. Or what is called paradigm change on
how to design a software with Haskell.
Haskell has its general-purpose features. Yet its strength is the
ability and ease of defining DSL by utilizing the higher order
\"stuff\" (like type class, composite function, monads, and arrows),
which to say the least, can be quite abstract and challenging.
I do come aross a question while reading the DSL page on Wikipedia.
http://en.wikipedia.org/wiki/Domain-specific_programming_language
In the Disadvantage section (near the end), there is an item -- hard
or impossible to debug. Can anybody explain why or what it means? And
how does it apply to Haskell?
-- steve
On 12/11/07, Brandon S. Allbery KF8NH
* Domain Specific Language (who needs it? other than academics and Wall Streeter?)
DSELs can be thought of as a programming methodology; as such, it has wide applicability, but most programmers don\'t think that way. Tcl was originally positioned as a \"DSEL enabler\" (write composable functions in C, tie them together in Tcl), but most programmers \"don\'t get it\" and so don\'t tend to use it as such. More recently, Lua seems to be using a similar philosophy with a little more success --- but mainly by limiting it to something which most programmers can deal with. Also compare how Perl and Python monoliths have replaced the original Unix philosophy in which the shell is a DSEL enabler (composing single-function programs like \"cat\" and \"sort\").
When it comes down to it, Haskell\'s strengths are only realizeable if you approach programming problems in a different way from most common languages. It\'s a fairly big leap, and arguably Haskell won\'t compete well in the mainstream until more programmers have made that leap.

On Wed, 2007-12-19 at 13:03 -0500, Steve Lihn wrote: [snip]
I do come aross a question while reading the DSL page on Wikipedia.
http://en.wikipedia.org/wiki/Domain-specific_programming_language
In the Disadvantage section (near the end), there is an item -- hard or impossible to debug. Can anybody explain why or what it means?
I can't think of anything in the pure concept of Domain Specific Languages that would make them hard or impossible to debug. You'd only have to write a good debugger for the language.
And how does it apply to Haskell?
A DSL embedded in Haskell has the advantage (and disadvantage) of being normal Haskell code, hence the normal Haskell debuggers will work. However, if the EDSL is presented as an entirely new language then non-Haskellers will obviously have problems understanding the generic Haskell debugger and error messages. Mattias

On Dec 19, 2007, at 13:03 , Steve Lihn wrote:
In the Disadvantage section (near the end), there is an item -- hard or impossible to debug. Can anybody explain why or what it means? And how does it apply to Haskell?
In the general case, you would need to design into your DSL both ability to debug programs written in it, and ability to debug its runtime/implementation. With experience, you can make the latter easier but in the case of complex DSLs even the best runtime support can be tricky. But in Haskell, not only is your DSL implemented in Haskell but it is implemented *as* Haskell combinators, so you can use the existing Haskell debugging features, *and* the implementation behaves like any other Haskell program so you are more likely to be able to figure out what's going on inside it given a reasonable debugging environment. The problem there being that debugging support is still fairly new in GHC 6.8.x (and well-nigh nonexistent in other Haskell implementations) and evolving. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Wed, 2007-12-19 at 13:03 -0500, Steve Lihn wrote: . . .
In the Disadvantage section (near the end), there is an item -- hard or impossible to debug. Can anybody explain why or what it means? And how does it apply to Haskell?
Lisp has long been touted as a good language for developing a DSL, one reason being it's macro system. However, it has also long been realized that DSLs implemented with macros can be extremely difficult to debug because by the time bugs manifest the (macro) source is long gone and its connection to the expansion text is difficult to determine. -- Bill Wood

Steve Lihn
I do come aross a question while reading the DSL page on Wikipedia.
http://en.wikipedia.org/wiki/Domain-specific_programming_language
In the Disadvantage section (near the end), there is an item -- hard or impossible to debug. Can anybody explain why or what it means? And how does it apply to Haskell?
I think I can give a good example of how this can apply to EMBEDDED DSLs. My library Dimensional (http://dimensional.googlecode.com) defines what someone referred to as a EDSL for working with physical units. The library leverages the Haskell type checker to provide static checking of physical dimensions. Without doing this I don't know how I could make such checking static. The downside of this is that while you will be informed at compile time if you physical calculations are incorrect the error message itself is rarely useful. Here is an example with lines numbered: 1 import Numeric.Units.Dimensional.Prelude 2 import qualified Prelude 3 4 -- The angular velocity of Earth's rotation (Soop p. 7). 5 phi = 360.985647 *~ (degree / day) 6 7 -- The gravitational parameter of Earth. 8 mu = 3.986004400008003e14 *~ (meter ^ pos3 / second ^ pos2) 9 10 -- The ideal geostationary radius and velocity. 11 r_GEO = cbrt (mu / phi ^ pos2) 12 v_GEO = phi * r_GEO 13 14 -- Something obviously wrong. 15 dont_try_this_at_home = v_GEO + mu Obviously we shouldn't be adding a velocity to a gravitational parameter on line 15 and the compiler will catch this. However, this is the error message from GHCi (6.6.1): DSLTest.hs:1:0: Couldn't match expected type `Numeric.NumType.Neg n' against inferred type `Numeric.NumType.Zero' When using functional dependencies to combine Numeric.NumType.Sub a Numeric.NumType.Zero a, arising from the instance declaration at Defined in Numeric.NumType Numeric.NumType.Sub Numeric.NumType.Zero Numeric.NumType.Zero (Numeric.NumType.Neg n), arising from use of `/' at DSLTest.hs:11:14-28 I think you will agree that this isn't very helpful in pin-pointing the problem. The compiler is pointing at the definition of 'r_GEO' which is twice removed from the actual offender. Stuff like this can make EDSLs difficult to debug. (In this particular example adding type signatures to all definitions will allow the compiler to pin-point the error to line 15, although the error message remains cryptic.) Hope that helps, Bjorn

arising from use of `/' at DSLTest.hs:11:14-28
Thanks for the example. I am particularly amazed GHC is complaining at
'/', not '+'. The type mismatch occurs (is reported) at much lower
level. It would be nice if there is a way to bump it up a couple
levels...
On Dec 26, 2007 12:56 PM, Bjorn Buckwalter
Steve Lihn
writes: I do come aross a question while reading the DSL page on Wikipedia.
http://en.wikipedia.org/wiki/Domain-specific_programming_language
In the Disadvantage section (near the end), there is an item -- hard or impossible to debug. Can anybody explain why or what it means? And how does it apply to Haskell?
I think I can give a good example of how this can apply to EMBEDDED DSLs. My library Dimensional (http://dimensional.googlecode.com) defines what someone referred to as a EDSL for working with physical units. The library leverages the Haskell type checker to provide static checking of physical dimensions. Without doing this I don't know how I could make such checking static.
The downside of this is that while you will be informed at compile time if you physical calculations are incorrect the error message itself is rarely useful. Here is an example with lines numbered:
1 import Numeric.Units.Dimensional.Prelude 2 import qualified Prelude 3 4 -- The angular velocity of Earth's rotation (Soop p. 7). 5 phi = 360.985647 *~ (degree / day) 6 7 -- The gravitational parameter of Earth. 8 mu = 3.986004400008003e14 *~ (meter ^ pos3 / second ^ pos2) 9 10 -- The ideal geostationary radius and velocity. 11 r_GEO = cbrt (mu / phi ^ pos2) 12 v_GEO = phi * r_GEO 13 14 -- Something obviously wrong. 15 dont_try_this_at_home = v_GEO + mu
Obviously we shouldn't be adding a velocity to a gravitational parameter on line 15 and the compiler will catch this. However, this is the error message from GHCi (6.6.1):
DSLTest.hs:1:0: Couldn't match expected type `Numeric.NumType.Neg n' against inferred type `Numeric.NumType.Zero' When using functional dependencies to combine Numeric.NumType.Sub a Numeric.NumType.Zero a, arising from the instance declaration at Defined in Numeric.NumType Numeric.NumType.Sub Numeric.NumType.Zero Numeric.NumType.Zero (Numeric.NumType.Neg n), arising from use of `/' at DSLTest.hs:11:14-28
I think you will agree that this isn't very helpful in pin-pointing the problem. The compiler is pointing at the definition of 'r_GEO' which is twice removed from the actual offender. Stuff like this can make EDSLs difficult to debug.
(In this particular example adding type signatures to all definitions will allow the compiler to pin-point the error to line 15, although the error message remains cryptic.)
Hope that helps, Bjorn
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Dec 26, 2007 10:28 PM, Steve Lihn
arising from use of `/' at DSLTest.hs:11:14-28
Thanks for the example. I am particularly amazed GHC is complaining at '/', not '+'. The type mismatch occurs (is reported) at much lower level. It would be nice if there is a way to bump it up a couple levels...
I suppose that is how the type inferencer works. To start with all it really "knows" is the types of 'phi' and 'mu'. Since it knows the type of 'mu' it can assume that 'v_GEO' has the same type, and from the definition of 'v_GEO' (and 'phi') it can infer a type for 'r_GEO'. But when checking that assumption against the definition of 'r_GEO' which depends on only 'phi' and 'mu' it realizes that things are amiss. (I'm just guessing here, the order, or way, in which the compiler does stuff may be totally different.) To be fair to the compiler it really has no way of knowing which definition is wrong without explicit type signatures. As I noted in my previous reply adding type signatures to all definitions allows the compiler to locate the error: In the second argument of `(+)', namely `mu' In the expression: v_GEO + mu I added this as an example to the library wiki[1]. The version of the code with type signatures is there and the whole page can be copy-pasted as literate haskell if you want to try it: [1] http://code.google.com/p/dimensional/wiki/ErrorMessagesAndDebugging
On Dec 26, 2007 12:56 PM, Bjorn Buckwalter
wrote: Steve Lihn
writes: I do come aross a question while reading the DSL page on Wikipedia.
http://en.wikipedia.org/wiki/Domain-specific_programming_language
In the Disadvantage section (near the end), there is an item -- hard or impossible to debug. Can anybody explain why or what it means? And how does it apply to Haskell?
I think I can give a good example of how this can apply to EMBEDDED DSLs. My library Dimensional (http://dimensional.googlecode.com) defines what someone referred to as a EDSL for working with physical units. The library leverages the Haskell type checker to provide static checking of physical dimensions. Without doing this I don't know how I could make such checking static.
The downside of this is that while you will be informed at compile time if you physical calculations are incorrect the error message itself is rarely useful. Here is an example with lines numbered:
1 import Numeric.Units.Dimensional.Prelude 2 import qualified Prelude 3 4 -- The angular velocity of Earth's rotation (Soop p. 7). 5 phi = 360.985647 *~ (degree / day) 6 7 -- The gravitational parameter of Earth. 8 mu = 3.986004400008003e14 *~ (meter ^ pos3 / second ^ pos2) 9 10 -- The ideal geostationary radius and velocity. 11 r_GEO = cbrt (mu / phi ^ pos2) 12 v_GEO = phi * r_GEO 13 14 -- Something obviously wrong. 15 dont_try_this_at_home = v_GEO + mu
Obviously we shouldn't be adding a velocity to a gravitational parameter on line 15 and the compiler will catch this. However, this is the error message from GHCi (6.6.1):
DSLTest.hs:1:0: Couldn't match expected type `Numeric.NumType.Neg n' against inferred type `Numeric.NumType.Zero' When using functional dependencies to combine Numeric.NumType.Sub a Numeric.NumType.Zero a, arising from the instance declaration at Defined in Numeric.NumType Numeric.NumType.Sub Numeric.NumType.Zero Numeric.NumType.Zero (Numeric.NumType.Neg n), arising from use of `/' at DSLTest.hs:11:14-28
I think you will agree that this isn't very helpful in pin-pointing the problem. The compiler is pointing at the definition of 'r_GEO' which is twice removed from the actual offender. Stuff like this can make EDSLs difficult to debug.
(In this particular example adding type signatures to all definitions will allow the compiler to pin-point the error to line 15, although the error message remains cryptic.)
Hope that helps, Bjorn
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (6)
-
Bill Wood
-
Bjorn Buckwalter
-
Brandon S. Allbery KF8NH
-
Lutz Donnerhacke
-
Mattias Bengtsson
-
Steve Lihn