A Declarative Language Problem
I started to use Scriptaculous on the web pages I have been building. But I have managed to take a simple task and turn it into a 4 hour debug session. This is a story about how I managed to screw up, again.
Technical Background
Scriptaculous uses Prototype. I have been using random parts of Prototype for over a year now, and I chose it because it does things the right way. In Prototype there are three Element methods pertinent to this story: show(), hide() and visible(). You can probably deduce what these are supposed to do.
I was trying to use Scriptaculous’ Effect.BlindUp() and Effect.BlindDown(), but they would not seem to work. I could get them to work in a simple example, but I could not get them to work on my particular page. There were four major bugs with my code:
- Scriptaculous needs tags inside the targeted DIV. Scriptaculous threw an error, I used the debugger to trace into the Scriptaculous code, and figured out what the HTML needed to be: Not a big problem.
- Prototype could not detect the display:none on some of my DIVs: Definitely frustrating, and I learned the hard way that CSS classes can NOT be used to set the display property. Turns out the caveat is right in the documentation. Too bad for me it was the last place I had expected it to be.
- Once the Scriptaculous effect had removed my DIV, it was still “visible” according to Prototype’s visible() method: Not a big problem, I just add an explicit callback to hide() the DIV when the effect has completed.
- Finally, and this is the big one: I could not get Scriptaculous to show my DIVs. I made sure I used an explicit style attribute, instead of CSS: <div id="kyle" style="display:none;visibility:hidden;">. You may see the problem, but I didn’t.
I did not see the problem because I have been hiding my DIVs like this for ages. You see, long ago I was trying to do simple DIV hiding. I stumbled upon the visibility style first, and it did not quite work; the DIV still consumed space despite being invisible. I searched further and found "display:none;" performed the extra collapsing feature I wanted. Put them together and I got what I wanted, and everything worked as expected. So when I got to using Scriptaculous, it did not occur to me that "visibility:hidden;" was the problem. It also did not help that the particular page I was testing this on showed no different whether I used “display:none;” or "visibility:hidden;". Once I got rid of "visibility:hidden;", everything worked fine. (BTW, Scriptaculous is awesome!)
Can I Learn From This?
When I stumble across a difficult bug, or an amazing feat of blindness, I like to analyze how I can prevent it in the future. But I believe this type of problem can not be prevented: Mostly because it is fundamental to declarative nature of HTML and CSS, but also because I will always have an occasional bout of selective blindness.
Declarative Languages Suck (for debugging)
My "visibility:hidden;" problem belongs to a class of outrageous bugs of have encountered over the years. I have been working in my secret lair devising a solution to this problem, and this instance has popped up to remind me of my project’s importance: If this does not get solved, the terrorists will win!
Declarative languages are awesome** because they only show what needs to be done, and not how to do it. But this benefit has it’s drawbacks: When there is a bug, you need to know how the program works to find our why there is a bug.
In the case of my first bug, Scriptaculous needs tags inside the targeted DIV, I could trace the implementation to find out why code failed. If Scriptaculous was a black box, or a declarative language, I would have spent much more time finding the right documentation, or finding the right HTML combination that made things work.
When it comes to the "visibility:hidden;" problem. If I could step through the code of the rendering engine, it should be apparent the reason why my DIV would not show: I would stumble across some code that looks like:
//DO NOTHING
}else{
element.render(boundingbox)
}//endif
which would emphasize what I did wrong.
Seeing a Pattern
I have experienced the same type of declarative problem in other domains too:
- A) SQL queries are hard to debug.
- B) Regular expressions are hard to debug.
We humans can debug these: we simply break-down the logic until we find the piece that caused the problem. But this iterative-divide-and-conquer technique is eerily reminiscent of techniques used on regular iterative programs before debuggers were available.
Back to my “visibility:hidden;” problem: I need a debugger that can focus on a particular DIV, and show me how it transforms that DIV, one step at a time.
Just so I am clear, I do not want to be actually stepping through the monstrous Mozilla code base. I would like a “Declarative Debugger” to use a much simpler analogy of what is happening in that code base. Maybe an HTML-to-HTML converter, which includes explicit CSS injection and javascript side effects. I should be able to watch my original HTML be converted to a context-free HTML, step-by-step, and I would be able to see my DIV get replaced by an empty div of the same size when it interprets the "visibility:hidden;" style I have given it.
Show macro graph changes and tracking instead of the micro variable values debugger show now.
What I Want
The debugger will map the object graph, to humane serialized form, which I will call the “representative string”. I want to select a particular substring, and call it the “focal string”, which represents my focal objects. This focal string acts like a breakpoint: stopping my debugger only when it encounters instructions that involve my focal objects.
- I want to step through transformations, one by one
- I want to be able to change the focus between each step; refining what object I am looking at
- I want to be able to run backwards, because I will probably only see the problem many steps after the error transformation has performed.
- I want to be able to alter formatting of the representative string easily
This last point is important. The representative string must suite my particular debugging problem: For example, I may not care about the internal representation of many container-like objects: I only want to know what they contain. The object graph used by container objects can have a greatly simplified representative strings.
Implementation Concerns
This type of debugger may not be possible without first building yet another declarative language.
We already have algorithms that can serialize graphs, but object graphs are more complex because the edges are named/typed. I hope that multi-type dominator analysis, and reasonable namespaces, can make general object graphs easy on the eyes.
A tool is needed to map local sub-graphs to their representative string; mapping words to the objects they represent. This involves integrating the current formatting preferences, and tracking changes in the object graph appropriately.
We will require cross-session representation: By making object allocation deterministic we should be able to correlate objects between debug sessions of the same program.
Summary
I would imagine that all declarative languages would be helped by this debugging feature
** Declarative languages are awesome because they are clear on what they represent: They are 1-1 mapping from symbols-concepts that make them easy to read and manipulate. Consider the difference between:
- 1) XML Swing layout
- 2) Java layout construciton
Despite the use of egregious XML, the first is easier to read than the Java version of the same. This is because the (unnecessary) how has been removed from the program specification, leaving only the essential what.