Future facts

marick edited this page Feb 27, 2013 · 9 revisions
Clone this wiki locally

Suppose I plan to write this function:

user=> (doc halts?)
-------------------------
user/halts?
([form & args])
  Form is a function definition: '(fn [...] ...)[form & args]).
  `halts?` determines if that function will halt when applied to the given args.
nil

I might write a couple of examples to clarify what halts? does:

(fact "`halts` determines if a program halts"
  (halts? '(fn [n] (+ n 2)) 1) => true
  (halts? '(fn recursive [n] (recursive (dec n))) 1) => false)

Implementing halts? will require some thought. While I'm thinking, I don't want to see a failure each time I check my suite of facts. But I don't want to comment out the fact, lest I forget to implement it. So I replace the fact token with future-fact:

(declare halts?)

(future-fact "`halts` determines if a program halts"
  (halts? '(fn [n] (+ n 2)) 1) => true
  (halts? '(fn recursive [n] (recursive (dec n))) 1) => false)

That produces this output:

No failure, but message printed

The string description after future-fact is not required. If it's not present, you just get a line number.

Rather than marking whole facts as "future", you can mark individual checkables. For example, here is a partial implementation of halts? that works for the vast majority of cases:

(defn halts?
  "Form is a function definition: '(fn [...] ...).
  `halts?` determines if that function will halt when applied to the given args."
  [form & args]
  true)

Now I want one of the checkables to be checked, the other to be a reminder. That can be done with the =future=> arrow:

(fact "`halts` determines if a program halts"
  (halts? '(fn [n] (+ n 2)) 1) => true
  (halts? '(fn recursive [n] (recursive (dec n))) 1) =future=> false)

Checking now produces this result:

No failure, but message printed

Notice that Midje printed the checkable that doesn't yet check out.

If you get tired of being nagged by "WORK TO DO" messages, but you don't want to delete them, you can turn off their printing by setting the :visible-future configuration option.