
Hi all, I'm a huge fan of TDD (Test-Driven Development) et I used to use tools such as RSpec (Ruby). So naturally, I looked to HSpec, but it seems not idiomatic in Haskell. I have a bunch of questions: - Do you do TDD? - Which tools do you use? - Is doctest "better" (in some senses) than HSpec? Why? - Are HSpec and Doctest complementary? If so, in which case do you use one or another? - Is there some Haskell-specific good practices do to TDD? Thanks in advance for your lights.

Well, for me TDD seems to be a poor substitute for type safety. And I specifically mean the level of type safety Haskell provides. In other languages TDD could be a good thing (although I value explorative programming too much), but in Haskell I think it's a waste of time. Отправлено с iPad
24 июня 2014 г., в 22:55, Gautier DI FOLCO
написал(а): Hi all,
I'm a huge fan of TDD (Test-Driven Development) et I used to use tools such as RSpec (Ruby). So naturally, I looked to HSpec, but it seems not idiomatic in Haskell. I have a bunch of questions: - Do you do TDD? - Which tools do you use? - Is doctest "better" (in some senses) than HSpec? Why? - Are HSpec and Doctest complementary? If so, in which case do you use one or another? - Is there some Haskell-specific good practices do to TDD?
Thanks in advance for your lights. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Tue, 24 Jun 2014 23:18:11 +0200, MigMit
Well, for me TDD seems to be a poor substitute for type safety.
And I specifically mean the level of type safety Haskell provides. In other languages TDD could be a good thing (although I value explorative programming too much), but in Haskell I think it's a waste of time.
Type safety does not cover everything; nearly an infinite number of functions could be made with the type: f :: Int -> Int To paraphrase prof. Edsger W. Dijkstra: No amount of type checking will prove a program correct Regards, Henk-Jan van Tuyl -- Folding@home What if you could share your unused computer power to help find a cure? In just 5 minutes you can join the world's biggest networked computer and get us closer sooner. Watch the video. http://folding.stanford.edu/ http://Van.Tuyl.eu/ http://members.chello.nl/hjgtuyl/tourdemonad.html Haskell programming --

On 06/25/2014 01:56 PM, Henk-Jan van Tuyl wrote:
On Tue, 24 Jun 2014 23:18:11 +0200, MigMit
wrote: Well, for me TDD seems to be a poor substitute for type safety.
And I specifically mean the level of type safety Haskell provides. In other languages TDD could be a good thing (although I value explorative programming too much), but in Haskell I think it's a waste of time.
Type safety does not cover everything; nearly an infinite number of functions could be made with the type: f :: Int -> Int
To paraphrase prof. Edsger W. Dijkstra: No amount of type checking will prove a program correct
Regards, Henk-Jan van Tuyl
While I disagree with initial view that testing is useless, I certainly disagree with this approach too. There are plenty proof-assistants using type-checking to prove programs correct. That's not to say Haskell itself is suited for such task. If you have a type system strong enough, classical tests are no longer required because you can encode all the properties you need in types proving at compile time that your program is in fact correct. -- Mateusz K.

On Wed, Jun 25, 2014 at 02:45:37PM +0200, Mateusz Kowalczyk wrote:
While I disagree with initial view that testing is useless, I certainly disagree with this approach too. There are plenty proof-assistants using type-checking to prove programs correct. That's not to say Haskell itself is suited for such task. If you have a type system strong enough, classical tests are no longer required because you can encode all the properties you need in types proving at compile time that your program is in fact correct.
For non-believers, here is a blog post that opened my eyes on the matter [1]. [1] http://lambda.jstolarek.com/2013/12/data-is-evidence/

On 06/25/2014 11:24 AM, Francesco Ariis wrote:
On Wed, Jun 25, 2014 at 02:45:37PM +0200, Mateusz Kowalczyk wrote:
While I disagree with initial view that testing is useless, I certainly disagree with this approach too. There are plenty proof-assistants using type-checking to prove programs correct. That's not to say Haskell itself is suited for such task. If you have a type system strong enough, classical tests are no longer required because you can encode all the properties you need in types proving at compile time that your program is in fact correct.
For non-believers, here is a blog post that opened my eyes on the matter [1].
None of that helps if you write the wrong program. Your program may typecheck, but if you're expecting "42" as output and your program hums the Star Trek theme instead, the fact that it correctly does the wrong thing won't be much consolation.

Again, nobody here suggests that tests aren't necessary. Отправлено с iPad
25 июня 2014 г., в 17:47, Michael Orlitzky
написал(а): On 06/25/2014 11:24 AM, Francesco Ariis wrote:
On Wed, Jun 25, 2014 at 02:45:37PM +0200, Mateusz Kowalczyk wrote: While I disagree with initial view that testing is useless, I certainly disagree with this approach too. There are plenty proof-assistants using type-checking to prove programs correct. That's not to say Haskell itself is suited for such task. If you have a type system strong enough, classical tests are no longer required because you can encode all the properties you need in types proving at compile time that your program is in fact correct.
For non-believers, here is a blog post that opened my eyes on the matter [1].
None of that helps if you write the wrong program. Your program may typecheck, but if you're expecting "42" as output and your program hums the Star Trek theme instead, the fact that it correctly does the wrong thing won't be much consolation.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Wed, Jun 25, 2014 at 11:05 AM, MigMit
Again, nobody here suggests that tests aren't necessary.
Doing so would make them a PETS member (People for the Ethical Treatment of Software): http://humor.mcf.com/microsloth/pets.html

On 2014-06-25 18:05, MigMit wrote:
Again, nobody here suggests that tests aren't necessary.
And rightfully so! TDD is not "a poor substitute for type safety" (as you put it in your earlier mail) at all. In fact, strong type systems complement test-driven development very nicely. An expressive type system greatly simplifies testing because the compiler can catch a larger classes of mistakes and because - in the case of pure functions - the function signatures very clearly communicate the required input and output. There are no hidden dependencies and there's no setup or tear-down work required. So I'd argue that test-driven development is relevant *because* of Haskell's type system, not *in spite of* it. -- Frerich Raabe - raabe@froglogic.com www.froglogic.com - Multi-Platform GUI Testing

And TDD is not the same as having tests, so please stop arguing for the second while pretending to be arguing for the first. Отправлено с iPhone
26 июня 2014 г., в 0:21, Frerich Raabe
написал(а): On 2014-06-25 18:05, MigMit wrote: Again, nobody here suggests that tests aren't necessary.
And rightfully so! TDD is not "a poor substitute for type safety" (as you put it in your earlier mail) at all.
In fact, strong type systems complement test-driven development very nicely. An expressive type system greatly simplifies testing because the compiler can catch a larger classes of mistakes and because - in the case of pure functions - the function signatures very clearly communicate the required input and output. There are no hidden dependencies and there's no setup or tear-down work required.
So I'd argue that test-driven development is relevant *because* of Haskell's type system, not *in spite of* it.
-- Frerich Raabe - raabe@froglogic.com www.froglogic.com - Multi-Platform GUI Testing
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Has anyone here actually done strict TDD?
I would expect strict TDD-based development (with no substantial design up
front) to gradually build up a system from fuzzy ideas. This would grow
increasingly unwieldy until the designer got fed up trying to keep it all
together and redesigned it from scratch. And for a large system there could
be several such redesign-completely episodes.
On Wed, Jun 25, 2014 at 6:26 PM, MigMit
And TDD is not the same as having tests, so please stop arguing for the second while pretending to be arguing for the first.
Отправлено с iPhone
26 июня 2014 г., в 0:21, Frerich Raabe
написал(а): On 2014-06-25 18:05, MigMit wrote: Again, nobody here suggests that tests aren't necessary.
And rightfully so! TDD is not "a poor substitute for type safety" (as you put it in your earlier mail) at all.
In fact, strong type systems complement test-driven development very nicely. An expressive type system greatly simplifies testing because the compiler can catch a larger classes of mistakes and because - in the case of pure functions - the function signatures very clearly communicate the required input and output. There are no hidden dependencies and there's no setup or tear-down work required.
So I'd argue that test-driven development is relevant *because* of Haskell's type system, not *in spite of* it.
-- Frerich Raabe - raabe@froglogic.com www.froglogic.com - Multi-Platform GUI Testing
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Johan Larson -- Toronto, Canada

On Jun 25, 2014, at 3:53 PM, Johan Larson
Has anyone here actually done strict TDD?
I would expect strict TDD-based development (with no substantial design up front) to gradually build up a system from fuzzy ideas. This would grow increasingly unwieldy until the designer got fed up trying to keep it all together and redesigned it from scratch. And for a large system there could be several such redesign-completely episodes.
I’ve done it a few times. What you’re missing is that good test coverage makes it incredibly easy to refactor, so you never have to redesign completely. Just refactor as necessary, when problems arise. TDD has a long history of being paired with agile design processes for this reason. -Kevin
On Wed, Jun 25, 2014 at 6:26 PM, MigMit
wrote: And TDD is not the same as having tests, so please stop arguing for the second while pretending to be arguing for the first. Отправлено с iPhone
26 июня 2014 г., в 0:21, Frerich Raabe
написал(а): On 2014-06-25 18:05, MigMit wrote: Again, nobody here suggests that tests aren't necessary.
And rightfully so! TDD is not "a poor substitute for type safety" (as you put it in your earlier mail) at all.
In fact, strong type systems complement test-driven development very nicely. An expressive type system greatly simplifies testing because the compiler can catch a larger classes of mistakes and because - in the case of pure functions - the function signatures very clearly communicate the required input and output. There are no hidden dependencies and there's no setup or tear-down work required.
So I'd argue that test-driven development is relevant *because* of Haskell's type system, not *in spite of* it.
-- Frerich Raabe - raabe@froglogic.com www.froglogic.com - Multi-Platform GUI Testing
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Johan Larson -- Toronto, Canada _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Jun 25, 2014, at 6:53 PM, Johan Larson
Has anyone here actually done strict TDD?
Yes. Routinely. For many years. With many programming languages, including Haskell.
I would expect strict TDD-based development (with no substantial design up front) to gradually build up a system from fuzzy ideas.
Why? Read Richard O’Keefe’s post from yesterday. Testing at the DSL level that he’s talking about is precisely where the tests in TDD exist. If it’s not a DSL it’ll be an API. In TDD, you do not test anywhere else. This includes regression test suites. There are constraints on an application’s architecture implied by TDD — you need an interface of some kind. If you feel testing at a more detailed level would be helpful when you write some part of the system, go ahead but delete those tests when you’re done. A recent talk about what TDD is, and isn’t, is at: http://www.infoq.com/presentations/tdd-original
This would grow increasingly unwieldy until the designer got fed up trying to keep it all together and redesigned it from scratch. And for a large system there could be several such redesign-completely episodes.
On Wed, Jun 25, 2014 at 6:26 PM, MigMit
wrote: And TDD is not the same as having tests, so please stop arguing for the second while pretending to be arguing for the first. Отправлено с iPhone
26 июня 2014 г., в 0:21, Frerich Raabe
написал(а): On 2014-06-25 18:05, MigMit wrote: Again, nobody here suggests that tests aren't necessary.
And rightfully so! TDD is not "a poor substitute for type safety" (as you put it in your earlier mail) at all.
In fact, strong type systems complement test-driven development very nicely. An expressive type system greatly simplifies testing because the compiler can catch a larger classes of mistakes and because - in the case of pure functions - the function signatures very clearly communicate the required input and output. There are no hidden dependencies and there's no setup or tear-down work required.
So I'd argue that test-driven development is relevant *because* of Haskell's type system, not *in spite of* it.
-- Frerich Raabe - raabe@froglogic.com www.froglogic.com - Multi-Platform GUI Testing
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Johan Larson -- Toronto, Canada _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Jun 25, 2014, at 6:53 PM, Johan Larson
Has anyone here actually done strict TDD?
Yes. Routinely. For many years. With many programming languages, including Haskell.
I would expect strict TDD-based development (with no substantial design up front) to gradually build up a system from fuzzy ideas.
Why? Read Richard O’Keefe’s post from yesterday. Testing at the DSL level that he’s talking about is precisely where the tests in TDD exist. If it’s not a DSL it’ll be an API. In TDD, you do not test anywhere else. This includes regression test suites. There are constraints on an application’s architecture implied by TDD — you need an interface of some kind. If you feel testing at a more detailed level would be helpful when you write some part of the system, go ahead but delete those tests when you’re done. A recent talk about what TDD is, and isn’t, is at: http://www.infoq.com/presentations/tdd-original
This would grow increasingly unwieldy until the designer got fed up trying to keep it all together and redesigned it from scratch. And for a large system there could be several such redesign-completely episodes.
On Wed, Jun 25, 2014 at 6:26 PM, MigMit
wrote: And TDD is not the same as having tests, so please stop arguing for the second while pretending to be arguing for the first. Отправлено с iPhone
26 июня 2014 г., в 0:21, Frerich Raabe
написал(а): On 2014-06-25 18:05, MigMit wrote: Again, nobody here suggests that tests aren't necessary.
And rightfully so! TDD is not "a poor substitute for type safety" (as you put it in your earlier mail) at all.
In fact, strong type systems complement test-driven development very nicely. An expressive type system greatly simplifies testing because the compiler can catch a larger classes of mistakes and because - in the case of pure functions - the function signatures very clearly communicate the required input and output. There are no hidden dependencies and there's no setup or tear-down work required.
So I'd argue that test-driven development is relevant *because* of Haskell's type system, not *in spite of* it.
-- Frerich Raabe - raabe@froglogic.com www.froglogic.com - Multi-Platform GUI Testing
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Johan Larson -- Toronto, Canada _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Wed, Jun 25, 2014 at 11:47:23AM -0400, Michael Orlitzky wrote:
On 06/25/2014 11:24 AM, Francesco Ariis wrote:
For non-believers, here is a blog post that opened my eyes on the matter [1].
None of that helps if you write the wrong program. Your program may typecheck, but if you're expecting "42" as output and your program hums the Star Trek theme instead, the fact that it correctly does the wrong thing won't be much consolation.
data Hum = HumStarTrekTheme | CountrySong data UltimateAnswerToEverything = FourtyTwo {- assorted datatypes and functions -} program :: a -> UltimateAnswerToEverything Getting serious again, the author of the post states: " A type system can be regarded as calculating a kind of static approximation to the run-time behaviours of the terms in a program. and then delivers (i.e. |order zero (suc b) = ge ge0| won't typecheck). I cannot but feel 90%+ of tests are just an "ad hoc, bug ridden, informally specified" type system.

On Wed, Jun 25, 2014 at 5:47 PM, Michael Orlitzky
On 06/25/2014 11:24 AM, Francesco Ariis wrote:
On Wed, Jun 25, 2014 at 02:45:37PM +0200, Mateusz Kowalczyk wrote:
While I disagree with initial view that testing is useless, I certainly disagree with this approach too. There are plenty proof-assistants using type-checking to prove programs correct. That's not to say Haskell itself is suited for such task. If you have a type system strong enough, classical tests are no longer required because you can encode all the properties you need in types proving at compile time that your program is in fact correct.
For non-believers, here is a blog post that opened my eyes on the matter [1].
None of that helps if you write the wrong program. Your program may typecheck, but if you're expecting "42" as output and your program hums the Star Trek theme instead, the fact that it correctly does the wrong thing won't be much consolation.
The same goes for any kind of testing, though. All these (writing the program, giving types for the program and testing the program) are different ways of specifying the same thing. The benefit from doing it twice in different ways, is that it's unlikely that you'll do it wrong twice *in the same way*. Erik

On Jun 26, 2014, at 3:10 AM, Erik Hesselink
On Wed, Jun 25, 2014 at 5:47 PM, Michael Orlitzky
wrote: On 06/25/2014 11:24 AM, Francesco Ariis wrote:
On Wed, Jun 25, 2014 at 02:45:37PM +0200, Mateusz Kowalczyk wrote:
While I disagree with initial view that testing is useless, I certainly disagree with this approach too. There are plenty proof-assistants using type-checking to prove programs correct. That's not to say Haskell itself is suited for such task. If you have a type system strong enough, classical tests are no longer required because you can encode all the properties you need in types proving at compile time that your program is in fact correct.
For non-believers, here is a blog post that opened my eyes on the matter [1].
None of that helps if you write the wrong program. Your program may typecheck, but if you're expecting "42" as output and your program hums the Star Trek theme instead, the fact that it correctly does the wrong thing won't be much consolation.
The same goes for any kind of testing, though. All these (writing the program, giving types for the program and testing the program) are different ways of specifying the same thing. The benefit from doing it twice in different ways, is that it's unlikely that you'll do it wrong twice *in the same way*.
So, tell me about QuickCheck… why is this thing thought so highly of? (this is a rhetorical question, I don’t need an answer :-) The problem isn’t really the unexpected humming of a song. It’s answering 43 when you’re expecting 42. Cheers, Bob
Erik _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Thu, Jun 26, 2014 at 2:24 PM, Bob Hutchison
On Jun 26, 2014, at 3:10 AM, Erik Hesselink
wrote: On Wed, Jun 25, 2014 at 5:47 PM, Michael Orlitzky
wrote: On 06/25/2014 11:24 AM, Francesco Ariis wrote:
On Wed, Jun 25, 2014 at 02:45:37PM +0200, Mateusz Kowalczyk wrote:
While I disagree with initial view that testing is useless, I certainly disagree with this approach too. There are plenty proof-assistants using type-checking to prove programs correct. That's not to say Haskell itself is suited for such task. If you have a type system strong enough, classical tests are no longer required because you can encode all the properties you need in types proving at compile time that your program is in fact correct.
For non-believers, here is a blog post that opened my eyes on the matter [1].
None of that helps if you write the wrong program. Your program may typecheck, but if you're expecting "42" as output and your program hums the Star Trek theme instead, the fact that it correctly does the wrong thing won't be much consolation.
The same goes for any kind of testing, though. All these (writing the program, giving types for the program and testing the program) are different ways of specifying the same thing. The benefit from doing it twice in different ways, is that it's unlikely that you'll do it wrong twice *in the same way*.
So, tell me about QuickCheck… why is this thing thought so highly of? (this is a rhetorical question, I don’t need an answer :-)
The problem isn’t really the unexpected humming of a song. It’s answering 43 when you’re expecting 42.
Are you replying to me, or Michael Orlitzky? Because I'm not sure what point you're making. I'm not arguing against the use of tests *or* types. I'm just saying neither is going to give you complete guarantees, but using either one is already much better than using none. Erik

I'm not replying to you nor Michael Orlitzky.
I'm replying to Richard A. O'Keefe.
You can see that by looking at which message was quoted below my actual
response.
I hope it will make things clearer, because I'm actually not arguing at all
against what you are saying :-)
On 26 June 2014 13:44, Erik Hesselink
On Thu, Jun 26, 2014 at 2:24 PM, Bob Hutchison
wrote: On Jun 26, 2014, at 3:10 AM, Erik Hesselink
wrote: On Wed, Jun 25, 2014 at 5:47 PM, Michael Orlitzky
On 06/25/2014 11:24 AM, Francesco Ariis wrote:
On Wed, Jun 25, 2014 at 02:45:37PM +0200, Mateusz Kowalczyk wrote:
While I disagree with initial view that testing is useless, I certainly disagree with this approach too. There are plenty proof-assistants using type-checking to prove programs correct. That's not to say Haskell itself is suited for such task. If you have a type system strong enough, classical tests are no longer required because you can encode all the properties you need in types proving at compile time that your
wrote: program
is in fact correct.
For non-believers, here is a blog post that opened my eyes on the matter [1].
None of that helps if you write the wrong program. Your program may typecheck, but if you're expecting "42" as output and your program hums the Star Trek theme instead, the fact that it correctly does the wrong thing won't be much consolation.
The same goes for any kind of testing, though. All these (writing the program, giving types for the program and testing the program) are different ways of specifying the same thing. The benefit from doing it twice in different ways, is that it's unlikely that you'll do it wrong twice *in the same way*.
So, tell me about QuickCheck… why is this thing thought so highly of? (this is a rhetorical question, I don’t need an answer :-)
The problem isn’t really the unexpected humming of a song. It’s answering 43 when you’re expecting 42.
Are you replying to me, or Michael Orlitzky? Because I'm not sure what point you're making. I'm not arguing against the use of tests *or* types. I'm just saying neither is going to give you complete guarantees, but using either one is already much better than using none.
Erik _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- *A\ois* http://twitter.com/aloiscochard http://github.com/aloiscochard

I feel like I'm reading a Monty Python sketch. On Thu, Jun 26, 2014 at 01:50:18PM +0100, Alois Cochard wrote:
I'm not replying to you nor Michael Orlitzky. I'm replying to Richard A. O'Keefe.
You can see that by looking at which message was quoted below my actual response. I hope it will make things clearer, because I'm actually not arguing at all against what you are saying :-)
On 26 June 2014 13:44, Erik Hesselink
wrote: On Thu, Jun 26, 2014 at 2:24 PM, Bob Hutchison
wrote: On Jun 26, 2014, at 3:10 AM, Erik Hesselink
wrote: On Wed, Jun 25, 2014 at 5:47 PM, Michael Orlitzky
On 06/25/2014 11:24 AM, Francesco Ariis wrote:
On Wed, Jun 25, 2014 at 02:45:37PM +0200, Mateusz Kowalczyk wrote: > While I disagree with initial view that testing is useless, I certainly > disagree with this approach too. There are plenty proof-assistants using > type-checking to prove programs correct. That's not to say Haskell > itself is suited for such task. If you have a type system strong enough, > classical tests are no longer required because you can encode all the > properties you need in types proving at compile time that your
wrote: program
> is in fact correct. >
For non-believers, here is a blog post that opened my eyes on the matter [1].
None of that helps if you write the wrong program. Your program may typecheck, but if you're expecting "42" as output and your program hums the Star Trek theme instead, the fact that it correctly does the wrong thing won't be much consolation.
The same goes for any kind of testing, though. All these (writing the program, giving types for the program and testing the program) are different ways of specifying the same thing. The benefit from doing it twice in different ways, is that it's unlikely that you'll do it wrong twice *in the same way*.
So, tell me about QuickCheck… why is this thing thought so highly of? (this is a rhetorical question, I don’t need an answer :-)
The problem isn’t really the unexpected humming of a song. It’s answering 43 when you’re expecting 42.
Are you replying to me, or Michael Orlitzky? Because I'm not sure what point you're making. I'm not arguing against the use of tests *or* types. I'm just saying neither is going to give you complete guarantees, but using either one is already much better than using none.
Erik _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- *A\ois* http://twitter.com/aloiscochard http://github.com/aloiscochard
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

That is a good description of my feeling right now as well :)
Erik
On Thu, Jun 26, 2014 at 2:59 PM, Tom Ellis
I feel like I'm reading a Monty Python sketch.
On Thu, Jun 26, 2014 at 01:50:18PM +0100, Alois Cochard wrote:
I'm not replying to you nor Michael Orlitzky. I'm replying to Richard A. O'Keefe.
You can see that by looking at which message was quoted below my actual response. I hope it will make things clearer, because I'm actually not arguing at all against what you are saying :-)
On 26 June 2014 13:44, Erik Hesselink
wrote: On Thu, Jun 26, 2014 at 2:24 PM, Bob Hutchison
wrote: On Jun 26, 2014, at 3:10 AM, Erik Hesselink
wrote: On Wed, Jun 25, 2014 at 5:47 PM, Michael Orlitzky
On 06/25/2014 11:24 AM, Francesco Ariis wrote: > On Wed, Jun 25, 2014 at 02:45:37PM +0200, Mateusz Kowalczyk wrote: >> While I disagree with initial view that testing is useless, I certainly >> disagree with this approach too. There are plenty proof-assistants using >> type-checking to prove programs correct. That's not to say Haskell >> itself is suited for such task. If you have a type system strong enough, >> classical tests are no longer required because you can encode all the >> properties you need in types proving at compile time that your
wrote: program
>> is in fact correct. >> > > For non-believers, here is a blog post that opened my eyes on the matter [1]. > > [1] http://lambda.jstolarek.com/2013/12/data-is-evidence/
None of that helps if you write the wrong program. Your program may typecheck, but if you're expecting "42" as output and your program hums the Star Trek theme instead, the fact that it correctly does the wrong thing won't be much consolation.
The same goes for any kind of testing, though. All these (writing the program, giving types for the program and testing the program) are different ways of specifying the same thing. The benefit from doing it twice in different ways, is that it's unlikely that you'll do it wrong twice *in the same way*.
So, tell me about QuickCheck… why is this thing thought so highly of? (this is a rhetorical question, I don’t need an answer :-)
The problem isn’t really the unexpected humming of a song. It’s answering 43 when you’re expecting 42.
Are you replying to me, or Michael Orlitzky? Because I'm not sure what point you're making. I'm not arguing against the use of tests *or* types. I'm just saying neither is going to give you complete guarantees, but using either one is already much better than using none.
Erik _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- *A\ois* http://twitter.com/aloiscochard http://github.com/aloiscochard
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 27/06/2014, at 12:50 AM, Alois Cochard wrote:
I'm not replying to you nor Michael Orlitzky. I'm replying to Richard A. O'Keefe.
What is this thing called QuickCheck? A *fantastic* tool from a great source which has been imitated more or less successfully for several other languages. The results tend to show just how amazing the Haskell type system is. (Yes, types AND tests!) Whenever I use it, it helps me.

On 06/26/2014 03:10 AM, Erik Hesselink wrote:
None of that helps if you write the wrong program. Your program may typecheck, but if you're expecting "42" as output and your program hums the Star Trek theme instead, the fact that it correctly does the wrong thing won't be much consolation.
The same goes for any kind of testing, though. All these (writing the program, giving types for the program and testing the program) are different ways of specifying the same thing. The benefit from doing it twice in different ways, is that it's unlikely that you'll do it wrong twice *in the same way*.
Erik
It guarantees that you've made an even number of mistakes =)

Great share thank you! There is incredible motivation for typed calculus
here: Where there are formal properties a proof may be pursued to build
reliable abstractions.
Where and how such methods are applied must still remain the purview of
thoughtful design.
Cheers,
Darren
On Jun 25, 2014 8:25 AM, "Francesco Ariis"
On Wed, Jun 25, 2014 at 02:45:37PM +0200, Mateusz Kowalczyk wrote:
While I disagree with initial view that testing is useless, I certainly disagree with this approach too. There are plenty proof-assistants using type-checking to prove programs correct. That's not to say Haskell itself is suited for such task. If you have a type system strong enough, classical tests are no longer required because you can encode all the properties you need in types proving at compile time that your program is in fact correct.
For non-believers, here is a blog post that opened my eyes on the matter [1].
[1] http://lambda.jstolarek.com/2013/12/data-is-evidence/ _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

That's true. I'm not stating tests aren't necessary; I'm stating TDD isn't necessary. You write tests, but you don't START with writing tests. Отправлено с iPad
25 июня 2014 г., в 13:56, "Henk-Jan van Tuyl"
написал(а): On Tue, 24 Jun 2014 23:18:11 +0200, MigMit
wrote: Well, for me TDD seems to be a poor substitute for type safety.
And I specifically mean the level of type safety Haskell provides. In other languages TDD could be a good thing (although I value explorative programming too much), but in Haskell I think it's a waste of time.
Type safety does not cover everything; nearly an infinite number of functions could be made with the type: f :: Int -> Int
To paraphrase prof. Edsger W. Dijkstra: No amount of type checking will prove a program correct
Regards, Henk-Jan van Tuyl
-- Folding@home What if you could share your unused computer power to help find a cure? In just 5 minutes you can join the world's biggest networked computer and get us closer sooner. Watch the video. http://folding.stanford.edu/
http://Van.Tuyl.eu/ http://members.chello.nl/hjgtuyl/tourdemonad.html Haskell programming --

On 06/24/2014 04:55 PM, Gautier DI FOLCO wrote:
Hi all,
I'm a huge fan of TDD (Test-Driven Development) et I used to use tools such as RSpec (Ruby). So naturally, I looked to HSpec, but it seems not idiomatic in Haskell. I have a bunch of questions: - Do you do TDD? - Which tools do you use? - Is doctest "better" (in some senses) than HSpec? Why? - Are HSpec and Doctest complementary? If so, in which case do you use one or another? - Is there some Haskell-specific good practices do to TDD?
Thanks in advance for your lights.
I like to use doctests for examples because they double as documentation. So if you have a function that's supposed to lowercase a string, you might show, -- Caps get lowercased: -- -- >>> lowercase_it "HELLO" -- "hello" -- -- And lowercase letters are left alone: -- -- >>> lowercase_it "hello" -- "hello" -- -- Numbers are unaffected: -- -- >>> lowercase_it "123" -- "123" -- -- It doesn't crash on the empty string: -- -- >>> lowercase_it "" -- "" -- If you think it would be useful to the reader, make it a doctest. For tests with a big setup/teardown -- like 20 lines of inserting junk into the database -- I use HUnit instead. For properties like idempotence, there's QuickCheck. I usually start out with doctest, because everything needs an example. Then if complicated tests or properties arise, I'll create a tasty[1] suite with HUnit[2]/QuickCheck[3] tests. Tasty basically groups all of your HUnit, QuickCheck, SmallCheck, etc. tests into one big suite with nicely-formatted output. HSpec is redundant once you have all of that in place, so I personally haven't found a niche for it yet. [1] http://hackage.haskell.org/package/tasty [2] http://hackage.haskell.org/package/tasty-hunit [3] http://hackage.haskell.org/package/tasty-quickcheck

I don't have a problem with using TDD *and* type-safety to the full extent
of usefulness, but the lifecycle/process isn't what TDD experts would call
proper TDD.
I do use HSpec, very happily. The author has done a truly excellent job
with it.
Process is something like:
write types, validate types
-> fill holes, validate terms against types
-> compose functions to see if results are sane, go back to 1st or 2nd step
if not.
-> Are there useful invariants QuickCheck can express? Write those first.
Repeat cycle as needed.
-> Decide on meaningful but compact functional/integration tests, repeat
cycle as needed.
Example HSpec tests (just functional/integration):
http://github.com/bitemyapp/bloodhound/
On Tue, Jun 24, 2014 at 3:55 PM, Gautier DI FOLCO wrote: Hi all, I'm a huge fan of TDD (Test-Driven Development) et I used to use tools
such as RSpec (Ruby). So naturally, I looked to HSpec, but it seems not
idiomatic in Haskell.
I have a bunch of questions:
- Do you do TDD?
- Which tools do you use?
- Is doctest "better" (in some senses) than HSpec? Why?
- Are HSpec and Doctest complementary? If so, in which case do you use one
or another?
- Is there some Haskell-specific good practices do to TDD? Thanks in advance for your lights. _______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Gautier DI FOLCO
writes:
I'm a huge fan of TDD (Test-Driven Development) et I used to use tools such as RSpec (Ruby). So naturally, I looked to HSpec, but it seems not idiomatic in Haskell.
I have a bunch of questions: - Do you do TDD?
Not as such, no, although there are times when I write what I want to say first, and then implement how to say it. This isn't my primary mode of development, however.
- Which tools do you use?
Doctest, hspec+hunit, quickcheck, fuzzcheck.
- Is doctest "better" (in some senses) than HSpec? Why?
I think they address different needs, actually.
- Are HSpec and Doctest complementary? If so, in which case do you use one or another?
I use doctest as much as possible, not only to create a test, but to demonstrate and motivate use of a function for anyone reading the docs. Hspec can handle more complicated tests that would be too heavyweight in that scenario.
- Is there some Haskell-specific good practices do to TDD?
First of all, invest in your types. As much as you can, avoid naked tuples, Strings or Ints. Use newtype and create type wrappers. Build new ADTs. Encode your invariants so that many of your "tests" become unnecessary. Then, when you have effects whose interplay cannot be encoded in types, focus on testing the possible runtime combinations. But even then, think about how you could encode that invariant in a type. John

For me TDD is highly overrated, and is abused as a buzz word by recruiter... In the context of writing a DSL, how one can start by the test? It's just impossible... TDD is okay if you fix a regression... sure I always fix bug that way, I start by creating a test that reproduce it... but I never ever do TDD when designing something new...
From my experience, usually people advocating TDD, are kind of person to focus more the methodology than the actual technical challenge... it might be what you are looking for... I don't.
On 24 June 2014 21:55, Gautier DI FOLCO
Hi all,
I'm a huge fan of TDD (Test-Driven Development) et I used to use tools such as RSpec (Ruby). So naturally, I looked to HSpec, but it seems not idiomatic in Haskell. I have a bunch of questions: - Do you do TDD? - Which tools do you use? - Is doctest "better" (in some senses) than HSpec? Why? - Are HSpec and Doctest complementary? If so, in which case do you use one or another? - Is there some Haskell-specific good practices do to TDD?
Thanks in advance for your lights.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- *A\ois* http://twitter.com/aloiscochard http://github.com/aloiscochard

On 26/06/2014, at 2:51 AM, Alois Cochard wrote:
For me TDD is highly overrated, and is abused as a buzz word by recruiter...
In the context of writing a DSL, how one can start by the test? It's just impossible...
I'm puzzled by this. You have some sort of fuzzy idea for a DSL. You're not sure exactly what it's going to look like, but you have a fair idea of what you want to be able to do with it. So you write some code in your DSL, making it up as you go. As you do this. you keep changing your mind about what's a nice way to say things, and you go back and revise earlier sketches. After a few hours to a few days, you now have some examples of things you'd like to be able to handle, and can start mining them for a a grammar and you can write some code to support them. And guess what, you have written your DSL tests first, because the examples you needed to do the *design* work are precisely test cases that your code should handle. My understanding of the history is that this is pretty much what happened when Erlang was designed.

Interesting, It's sounds like your definition of `TDD` is what is my
definition of `solving problem`.
My point was that I don't want to write test for a grammar that I might
realize during further design that is wrong, this would be just complete
wasted effort... Instead I just test as a way to tryout my DSL... but
really to me it does *not* relate to TDD... because I can do the same with
just a REPL and the history of it...
I wish that definition you use was the same understood by the industry, but
it is not the way it was presented to me when I discussed with TDD
enthusiast in the past... maybe things changed.
Cheers
On 25 June 2014 22:44, Richard A. O'Keefe
On 26/06/2014, at 2:51 AM, Alois Cochard wrote:
For me TDD is highly overrated, and is abused as a buzz word by recruiter...
In the context of writing a DSL, how one can start by the test? It's just impossible...
I'm puzzled by this.
You have some sort of fuzzy idea for a DSL. You're not sure exactly what it's going to look like, but you have a fair idea of what you want to be able to do with it.
So you write some code in your DSL, making it up as you go. As you do this. you keep changing your mind about what's a nice way to say things, and you go back and revise earlier sketches.
After a few hours to a few days, you now have some examples of things you'd like to be able to handle, and can start mining them for a a grammar and you can write some code to support them.
And guess what, you have written your DSL tests first, because the examples you needed to do the *design* work are precisely test cases that your code should handle.
My understanding of the history is that this is pretty much what happened when Erlang was designed.
-- *A\ois* http://twitter.com/aloiscochard http://github.com/aloiscochard

On 27/06/2014, at 12:37 AM, Alois Cochard wrote:
Interesting, It's sounds like your definition of `TDD` is what is my definition of `solving problem`.
Not exactly. It's problem solving/design activity PLUS recording aspects of your decisions as machine-readable tests.
My point was that I don't want to write test for a grammar that I might realize during further design that is wrong, this would be just complete wasted effort...
For one thing, tests can be automatically generated from a grammar. The first time I demonstrated this to a class of students, I said "now, here I've got this program that I wrote a few years ago and I know it works, this is just demonstrating how you can generate tests from a grammar." And then the very first generated test revealed a bug. At that point I was Enlightened. But the most important thing here is that a grammar and an API are not that different. The whole *point* of writing your tests first is that the interfaces we design are just another of the things we get wrong. It's way too easy to design an interface, code it up, start testing, and discover that something that should be easy is somewhere between difficult and impossible, and fixing it requires a redesign. (I would say that the original Document Object Model looks very much like something that was frozen before being checked this way. Certainly everything *I* wanted to do with it was unspeakably clumsy. Hooray for Haskell and document *value* models!) Writing test cases is one way in which "further design" happens; if a test that should be straightforward isn't, *that* is when you "release .. that is wrong". None of this is new. Back in the 1960s when people like Dijkstra were talking about top down design, they were talking about writing a program *as if* some helpful genie provided all the library support you needed, *playing* around and getting the design right, and only *then* implementing the library. (And when doing that, you do the same thing all over again.)
Instead I just test as a way to tryout my DSL... but really to me it does *not* relate to TDD... because I can do the same with just a REPL and the history of it...
Using a REPL (provided your system saves a transcript so that you can replay tests later) has two main problems: (1) you can't do it until the code and its interface *exist*, whereas writing tests earlier can save you time wasted on implementing the wrong interface (2) using a REPL is apt to be a bit haphazard; thinking about your tests off-line you can get more coverage with less work. Don't mistake me. I am *not* good at testing yet. The only reason I'm defending TDD is that I have after too many years finally learned that "if it isn't tested it doesn't work" is true of *MY* code, so the earlier I test something the less horribly embarrassed I'm going to be.
I wish that definition you use was the same understood by the industry, but it is not the way it was presented to me when I discussed with TDD enthusiast in the past... maybe things changed.
We are not called to be right. We are called to improve. Learn from many masters but obey none.

On 27 June 2014 00:22, Richard A. O'Keefe
For one thing, tests can be automatically generated from a grammar. The first time I demonstrated this to a class of students, I said "now, here I've got this program that I wrote a few years ago and I know it works, this is just demonstrating how you can generate tests from a grammar." And then the very first generated test revealed a bug. At that point I was Enlightened.
Sure that is awesome, same kind of thing as using QuickCheck in a way... but do you consider this as TDD? I always seen TDD as "writing test first", where here you generate them once you have the grammar... that feel different to me, but as said before I'm realizing my definition was wrong.
But the most important thing here is that a grammar and an API are not that different.
Yeah I completely agree, the fact that I was trying to make a point specific to DSL design is wrong... it's should be the same really.
The whole *point* of writing your tests first is that the interfaces we design are just another of the things we get wrong.
But don't you think this particular step can be achieved in your head? Maybe not for complex thing, but at least it work for me for simple case... I test the interface in my head or on paper before actually coding them (I'm not saying *implementing* them!)
Don't mistake me. I am *not* good at testing yet. The only reason I'm defending TDD is that I have after too many years finally learned that "if it isn't tested it doesn't work" is true of *MY* code, so the earlier I test something the less horribly embarrassed I'm going to be.
That's for sure, but that point is imo about testing in general and not TDD in particular. Once you deliver a piece of work, it should be proven it work... Maybe doing it earlier help, but that's more about fighting procrastination than anything else, because I'm sure you hate as much as me writing tests ;-)
We are not called to be right. We are called to improve. Learn from many masters but obey none.
Nice, a wise advice that I'll surely remember. -- *A\ois* http://twitter.com/aloiscochard http://github.com/aloiscochard

On 27 June 2014 00:22, Richard A. O'Keefe
wrote: For one thing, tests can be automatically generated from a grammar. The first time I demonstrated this to a class of students, I said "now, here I've got this program that I wrote a few years ago and I know it works, this is just demonstrating how you can generate tests from a grammar." And then the very first generated test revealed a bug. At that point I was Enlightened.
Sure that is awesome, same kind of thing as using QuickCheck in a way... but do you consider this as TDD?
No, OF COURSE NOT. I never said it was. All I was doing is saying that generating tests from a grammar is easy, so don't ever believe "this might not be the real grammar so it would be too much wasted work testing from it."
I always seen TDD as "writing test first", where here you generate them once you have the grammar... that feel different to me, but as said before I'm realizing my definition was wrong.
Having a GRAMMAR is one thing. Having a PARSER is another. Suppose I say "write me some tests for function f". You will say back, if you have any sense: "I cannot possibly do that until I have some idea what f is supposed to do." Not the most rabid advocate of TDD would claim that you can write tests in a knowledge vacuum. The strongest claim I've seen is that the process of constructing the specification and the process of constructing the tests can be so interwoven that they are the same activity, but even then you have to have *some* idea of what you want before you start.
But don't you think this particular step can be achieved in your head? Maybe not for complex thing, but at least it work for me for simple case...
Everything works for simple cases. The problem is that some of the things we think are simple aren't. Programmers tend to be an optimistic lot, and we tend not to think of all the things that can go wrong. (Like someone I once worked with who used to teach students NOT to check the result of malloc() because on today's machines they would never run out of memory. I kid you not.) For example, there was one specification I implemented where there was a signed integer parameter and the original designers neither said what was supposed to happen if it was negative, nor said that it was an error or undefined or anything. I reckon they just never thought about it. Here's another one. There is a standard for a certain programming language which states that (1) the timestamp datatype uses UTC (2) timestamps can be calculated for thousands of years in the future. This requires a computer that can predict the choices of a human committee far into the future, as you discover as soon as you try to construct test cases and realise that you don't actually know what addSeconds(new TimeStamp(), 10*1000*1000) should be because your leap second table doesn't extend into the future.
Once you deliver a piece of work, it should be proven it work... Maybe doing it earlier help, but that's more about fighting procrastination than anything else, because I'm sure you hate as much as me writing tests ;-)
You will find that most traditional books about testing (including Boris Beizer's, for example) say that the earlier a bug goes into a system, the longer it stays and the harder it is to get it out. That's not a *proof* that doing testing as early as you can will save you effort, but it's suggestive. And one thing is certain, if you think about testing early, you'll aim for a design that *can* be tested.

On 2014-06-24 22:55, Gautier DI FOLCO wrote:
Hi all,
I'm a huge fan of TDD (Test-Driven Development) et I used to use tools such as RSpec (Ruby). So naturally, I looked to HSpec, but it seems not idiomatic in Haskell. I have a bunch of questions: - Do you do TDD? - Which tools do you use? - Is doctest "better" (in some senses) than HSpec? Why? - Are HSpec and Doctest complementary? If so, in which case do you use one or another? - Is there some Haskell-specific good practices do to TDD?
Thanks in advance for your lights.
I suspect most people practice "the other TDD", namely *Type*-Directed Development. At its most basic you just start by writing out all the type signatures (and type classes and whatnot) that you expect everything to have with "undefined" as the body of the functions. Then you just fill in the "undefined"s. Regards,

On 2014-06-25 18:28, Bardur Arantsson wrote:
On 2014-06-24 22:55, Gautier DI FOLCO wrote:
Hi all,
I'm a huge fan of TDD (Test-Driven Development) et I used to use tools such as RSpec (Ruby). So naturally, I looked to HSpec, but it seems not idiomatic in Haskell. I have a bunch of questions: - Do you do TDD? - Which tools do you use? - Is doctest "better" (in some senses) than HSpec? Why? - Are HSpec and Doctest complementary? If so, in which case do you use one or another? - Is there some Haskell-specific good practices do to TDD?
Thanks in advance for your lights.
I suspect most people practice "the other TDD", namely *Type*-Directed Development.
*"most people around here practice"

Hi all, Thanks for all your answers, I didn't expect to create a debate but I think it's the best place to make my own point of view (or at least the best place to decide where to start deeper investigations/experiments). So, thank you all.

I'm a huge fan of TDD (Test-Driven Development) et I used to use tools such as RSpec (Ruby). So naturally, I looked to HSpec, but it seems not idiomatic in Haskell. I have a bunch of questions: - Do you do TDD? - Which tools do you use? - Is doctest "better" (in some senses) than HSpec? Why? - Are HSpec and Doctest complementary? If so, in which case do you use one or another? - Is there some Haskell-specific good practices do to TDD?
Both doctest and HSpec are implemented by Simon (the same author). His intention is described here: https://github.com/kazu-yamamoto/unit-test-example/blob/master/markdown/en/t... Probably Haskell specific feature is QuickCheck integration. Now GHC 7.8 is out, we can use the "prop>" keyword in doctest cases, too. Enjoy. --Kazu

Gautier DI FOLCO wrote:
Hi all,
I'm a huge fan of TDD (Test-Driven Development) et I used to use tools such as RSpec (Ruby). So naturally, I looked to HSpec, but it seems not idiomatic in Haskell. I have a bunch of questions: - Do you do TDD? - Which tools do you use? - Is doctest "better" (in some senses) than HSpec? Why? - Are HSpec and Doctest complementary? If so, in which case do you use one or another? - Is there some Haskell-specific good practices do to TDD?
In languages other than Haskell I do sometimes write tests first and practive real TDD. I Haskell writing test first seems a little ridculous. What I tend to do is: * Write the types. * Make sure the types interact together. * Fill in the functions. * For stuff that cannot be enforced by types, write tests. For tests I use Hspec (both canned example test and QuickCheck style property tests) but intend to start suplementing it with doctest so that example code in the docstring comments is tested for correctness. Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/

I often write tests first, as a way of testing my understanding. I figure out in my head what I think a certain function should return, and write that down first. That way I have a "second implementation" (the one in my head) that hasn't been compromised by seeing the actual results. Otherwise I'd be tempted to copy and paste actual output into the test and inspect it to make sure it makes sense. I think what kind of tests are relevant depends more strongly on what kind of program you are writing, than what language you are writing in. My program has a lot of complexity that's hard to put in types, and is also not amenable to QuickCheck, so I wind up with lots of 'equal (f x y z) [expected, result, ...]' type tests, and those can work well if you write them first. It's somewhat similar to compiler, so it's analogous to ghc's "expected output" and "should fail" tests. Another style of program could be totally different.
participants (23)
-
Alois Cochard
-
Bardur Arantsson
-
Bob Hutchison
-
Christopher Allen
-
Darren Grant
-
Erik de Castro Lopo
-
Erik Hesselink
-
Evan Laforge
-
Francesco Ariis
-
Frerich Raabe
-
Gautier DI FOLCO
-
Henk-Jan van Tuyl
-
Johan Larson
-
John Wiegley
-
Kazu Yamamoto
-
Kevin Nardi
-
Mateusz Kowalczyk
-
Michael Orlitzky
-
MigMit
-
Mike Meyer
-
ok@cs.otago.ac.nz
-
Richard A. O'Keefe
-
Tom Ellis