Goals

From these examples, I've been trying to extract a real problem which "Is a Cow an Animal?" is trying to solve.
Goal #1
implement the rules below, rejecting at runtime *any* malformed program.

As seen below, it's pretty easy.

Goal #2
try to enforce the rules at compile-time,

this can be


Description of the World

general rules:

animals' accepted food:

IMPORTANT: feeding a cow with something else than grass is a fatal error (same for feeding a human with grass...)

when slaughtered:


Implementations

Python0/11 should_fails detected at compile-time
Ruby0/11 should_fails detected at compile-time
Scheme0/11 should_fails detected at compile-time
C++5/11 should_fails detected at compile-time
C++ with parametric class7/11 should_fails detected at compile-time
C++ with parametric class and diamond multiple-inheritance8/11 should_fails detected at compile-time
C++ with parametric class and eaters tied to the food8/11 should_fails detected at compile-time
OCaml5/11 should_fails detected at compile-time
OCaml with parametric class tentative1/11 should_fails succeeds :-(, 7/11 should_fails detected at compile-time
OCaml with parametric class and variants8/11 should_fails detected at compile-time
Prolog tentative3/11 should_fails succeeds :-( and 0/11 detected at compile-time
Haskell faking OO, no monad5/11 should_fails detected at compile-time, but doesn't ensure previous elements are not used
Haskell with phantom types (simple)8/11 should_fails detected at compile-time, but doesn't ensure previous elements are not used
Haskell with phantom types (with type hierarchy)8/11 should_fails detected at compile-time, but doesn't ensure previous elements are not used
Haskell with monads and phantom types8/11 should_fails detected at compile-time
Scala11/11 should_fails detected at compile-time, but doesn't ensure previous elements are not used
ATS (test code)11/11 should_fails detected at compile-time
Typescript8/11 should_fails detected at compile-time
Java5/11 should_fails detected at compile-time
Java with generics8/11 should_fails detected at compile-time

Test example

(using Python's syntax, see the various implementations for some other syntaxes)

grass    = new_grass(5)
carrot   = new_carrot(10)

a_rabbit      = new_rabbit(100)
a_cow         = new_cow(1000)
a_human       = new_human(300)
another_human = new_human(350)

for o in [ a_rabbit, a_cow, a_human ]:
    print "%s -> %d" % (o.name, o.energy)

a_rabbit.eat(carrot)
a_cow.eat(grass)

a_dead_rabbit = a_rabbit.slaughter()
a_beef = a_cow.slaughter()

a_human.eat(carrot)
a_human.eat(carrot)
a_human.eat(a_beef)
a_human.eat(a_dead_rabbit)

a_human.eat(another_human.slaughter())

if a_human.energy != 1785: raise "failed"
and here are some examples that should fail
new_cow(10).slaughter().eat(grass) # meat (food) can't eat
new_cow(10).slaughter().slaughter() # meat (food) can't be slaughtered
carrot.eat(grass)      # vegetable (food) can't eat
carrot.slaughter()     # vegetable (food) can't be slaughtered

new_cow(10).eat(carrot) # cow do not eat carrot
new_cow(10).eat(new_cow(10).slaughter()) # cow do not eat beef
a_human.eat(new_cow(10)) # can't eat live animals
a_human.eat(grass)     # human do not eat grass
a_human.eat(a_beef)    # a_beef is already eaten
a_cow.eat(grass)       # a_cow is dead, it can't eat
a_cow.slaughter()      # a_cow is dead, it can't be slaughtered again

Remarks


Pixel
This document is licensed under GFDL (GNU Free Documentation License).

Release: $Id$