NOTE: This is only a brainstorming document. It is not meant to finalize any syntax or approach.
The idea is to put everything related to a class and it's subclasses into a control table. This differs from our prior approach in that:
Example "Animals" Table
Subclass | Sound | FoodType | Domestic | Train |
---|---|---|---|---|
define default | "I have no sound" | % notrain() | ||
define evaluator | playsound(@) | |||
define assignor | % if not in(@,"Y","N") {raiseErr()} else {return @} |
|||
Wolf | howl | carn. | N | |
Rat | % rodentsound() | misc. | N | |
Cow | moo | herb. | Y | |
Dog | ruf ruf | misc. | Y | % while not trained{try(); reward()} |
The blue shaded rows represent "definition" subclasses. In our code version they are combined into a single class definition.
The "@" symbol represents the value looked up from the relevant subclass. The percent symbol represents that a method/function is to supply the value of the attribute or method instead of a value. Notice how the Rat sound is calculated instead of hardwired into the table. The distinction between a method and an attribute are blurred. (These symbols are only preliminary suggestions.)
The "evaluator" row triggers whenever the corresponding method is called:
Cow.sound()Here, "playsound()" is executed in this case with the cow's sound string passed to it. However, if we did:
x = Cow.soundthen only "moo" is returned. If we did:
x = Rat.soundthen rodentSound() would be executed in order to generate the value. If we requested:
Rat.sound()then both rodentSound() and playSound() would be executed. It would be roughly equivalent to:
playSound(rodentSound())
The "assignor" row evaluates whenever an assignment is made to a subclass. For example, if:
Dog.domestic = "Z"is attempted, then an error is triggered because the corresponding assignor cell performs a validation.
Now for the code version:
class Animals { method Sound { temp = @ if empty(temp) { // implement default temp = "I have no sound" } return playsound(temp) } method required FoodType { return @ } method required Domestic { return @ } method assignor Domestic { if not in(@,"Y","N") {raiseErr()} else {return @} } method Train { if empty(@) { return notrain() } else { return @ } } } // end class subclass Wolf extends animals { method sound {return "howl"} method foodtype {return "carn."} method domestic {return "N" } } subclass Rat extends animals { method sound {return rodentsound() } method foodtype {return "misc." } method domestic {return "N" } } subclass Cow extends animals { method sound {return "moo"} method foodtype {return "herb."} method domestic {return "Y"} } subclass Dog extends animals { method sound {return "ruf ruf"} method foodtype {return "misc."} method domestic {return "Y"} method train {return while not trained{try(); reward()} } }