Journal of my investigation into the development of a new programming language
Testability of Procedures
I'm using the Pascal distinction of functions (which return a value) and procedures (which don't) here. Procedures in the C family are just functions with the void return type.
For zero button testing, I've come up with syntax that I'm very happy with: expect...returns. This allows tests to be written right in the function body. For instance:
. . expect 1 returns 2
. . return 2 * x
For test-driven development, this seems like a great way to go - you write the function name, then immediately the test(s). With zero button testing, the test name starts out yellow (it has no tests) then turns red as soon as the first test is written (and fails, because the function doesn't return anything
yet). Then you write the function body, correctly, and it all turns its natural shade of white or perhaps gray. As you type.
A little extension to this to answer the immediate question of how to test member functions - in addition to expect
, let's add archetype
to our list of keywords. With that, now we have:
. . archetype none(0, 0)
. . archetype some(1, 2)
. . contains x:
. . . . expect none 1 returns false
. . . . expect some 1 returns true
. . . . x < low? return false
. . . . x >= high? return false
. . . . return true
That is to say, we expect that when the empty range none is asked whether it contains 1, it should (and does) return false; when some is asked, it returns true. Some contains 1 and none doesn't.
That's all well and good - but when it comes to procedures, which don't return anything at all, I don't know how to express the tests so nicely. Invoking the routine and testing its effects are separate steps. So - a puzzle.
works well for functions, but not procedures.
One of the nice features of C# is properties; from the outside they behave like instance variables but internally they act more like functions. Each property has a getter and/or setter (named, reasonably enough, "get" and "set").
C#'s setters use the keyword "value" for the value being passed in. If I put properties into my language, I think I may instead use the name of the thing, as in this example, from the range class:
. . get: return low + length - 1
. . set: length = high - low + 1
Of course this is inconsistent - the meaning of high
everywhere else in the program will be to invoke the getter or setter - but it seems very clear. Intention-revealing.
I've been playing with C# and Python lately, working my way toward an editor for my language, and working on some of the language ideas as well. The picture below is a screenshot from my C# app, holding Python code. I like Python's indentation-based blocks, and plan to use the same approach in my own language.
I was focussing on the ability to highlight code that failed tests, as I did in my "zero button testing" prototypes, and realized that I wanted to have both syntax coloring (keywords in blue, method names in green, etc.) and
correctness coloring, at the same time. In the ZBT prototypes, I used text forecolor to indicate correctness; for the new app, I want to reserve forecolor for syntax and use background shading to indicate correctness.
As I explored the ways to do background shading, it occurred to me that in addition to the very limited red-for-error, yellow-for-untested palette I was planning, it would also be possible to do a more nuanced coloring that showed nesting level. I like it; it makes it easy to focus attention on one particular block. Note that in addition to the line-by-line coloring, I'm also splitting individual lines at the colon (and, for my own language, at the question mark); this emphasizes the columnar nature of some sections of code; I think it might work well with SQL, which I've long preferred in a nice columnar format.