Philip Greenspun’s tenth rule of programming is “Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.” And this outlines one manifestation of what I like to call the Inside-Out problem.
The inside-out problem is when an application provides a lot of granular features wrapped up in a way that solves a lot of their user’s problems, but rather than attempt to solve all of them (or more), someone decides that the inside of the application needs to be presented to the outside world in some way. This can be done in a variety of ways, including providing a scripting language or providing hooks for a scripting language of some kind or some other way of getting the guts of the application exposed to the user.
This is nearly always problematic. Questions arise like, “what language?” “how do I expose/reflect my data model?” “how do I expose my functional model?” “how do I do this without fundamentally breaking my app?”
Sadly, a lot of engineers do this and make very poor choices, for example, implementing a broken version of Lisp – which by the way is very easy to do. If you look at SICP in chapter 4, there is an entire outline for how to implement Scheme in Scheme, but this is very easy to adapt to other languages. The DailyWTF ran a contest based on writing a 4 function calculator and rather than just implementing the calculator, I wrote a broken Lisp interpreter that has basic hooks for adding 1, subtracting 1, conditionals, and recursion. From that, I implemented the actual calculator as horrible script that bound functions to keys. It was truly terrible, but it exemplifies the inside out problem.
Sometimes it makes sense to have it. Emacs is an example where it works reasonably well in that the entire editor is built around the precept that it should be completely extensible and that decision was made from the start.
Other times, it doesn’t turn out so well and some poor engineer will decide that their extensibility model for a UNIX app is to execute a shell script pointed to by the user or even worse, to use the UNIX call system() to execute a user task.
The solution is actually very simple and it is to realize that your application’s implementation language is your scripting language. If you can successfully implement the underpinnings of your application as a series of solid API’s, then you have no need for a scripting language as you can provide the API to the customers to use directly rather than try to jam a scripting language into your existing application.
In addition, if you have designed your API well, then it should be straight-forward to wrap it so it is consumable from other languages. For example, it’s straightforward to wrap a non-chatty C/C++ API in .NET or Java, but less so to wrap a .NET API in a C library (although COM helps).
About the AuthorFollow on Twitter More Content by Steve Hawley