David Hopwood <...nospam....uk> wrote: > A good debugger is invaluable regardless of your attitude > to type systems.
I found that certain language features help greatly in pinning the errors, when programming in my own impure fp language (PILS). Originally, I implemented a single-stepping debugger for the language, but I trashed it for three reasons, of which two are rather uninteresting here: it messed up the GUI system, and the evaluation order of PILS made single-stepping a confusing experience. The interesting reason is: I didn't need single-stepping, partly because the programming system is unit-test friendly, partly because of language features that seem to mimick the concept of taking responsibility. Basically, the PILS execution mechanism is pessimistic. When a function is called, the assumption is it won't work, and the only way the function can return a result is by throwing an exception. So, if a function call doesn't throw an exception, it has failed and execution will stop unless the function call is explicitly marked as fault tolerant, as in f (x) else "undefined" This has been merged with tail call flattening - rather than throwing the result, an (expression, binding) thing is thrown (I guess .NET'ers would call it an anonymous parameterless delegate), and the expression is then evaluated after the throw. Mimickally speaking, when a function body performs this throw, it takes responsibility for getting the job done, and if it fails, it will suffer the peril of having its guts exposed in public by the error message window - much like certain medieval penal systems. I will spare you for the gory details, just let me add that to honor the demands of modern bureaucracy, I added a "try the other office" feature so that there are ways of getting things done without ever taking responsibility. Strangely, this all started 20 years ago as I struggled implementing an early PILS version on an 8-bit Z80 processor, at a blazing 4 MHz. I needed a fast way of escaping from a failing pattern match, and it turned out the conditional return operation of this particular processor was the fastest I could get. Somehow, the concept of "if it returns, it's bad" crept into the language design. I was puzzled by its expressiveness and the ease of using it, only years later did I realize that its ease of use came from the mimicking of responsibility. I'm still puzzled that the notion of mimicking a cultural/ social concept came from a microprocessor instruction. It seems like I - and perhaps computer language designers in general - have a blind spot. We dig physical objects and mathematical theories, and don't take hints from the "soft sciences"... Perhaps I'm over-generalizing, it just strikes me that the dispute always seems to stand between math versus object orientation, with seemingly no systematic attempts at utilizing insigts from the study of languages and cultural concepts. It's like as if COBOL and VB scared us from ever considering the prospect of making programming languages readable to the uninitiated. -- http://mail.python.org/mailman/listinfo/python-list