Water 5-Type and Object System-Object System
class and type class
Contract
Return typewob
No input parameters.
Parameter kindDefault valueType
Other unkeyed argumentsopt with ekind of expression
Other keyed argumentsopt with ekind of code
Water Contract
<class class
  _name_argument=req=wob=ekind.expression
  _body         =opt=vector
  _return_type  =wob
  _other_keyed  =opt=wob="_add_to_environment"
  _other_unkeyed=opt=wob=ekind.expression=wob="_body"
/>

In Water, every piece of data (including code) is represented by an object. Objects can take on roles depending on how they are used. 'Class' is such a role. An object can be considered to be a class if it is used to make 'instances' of the class. 'Instance' is, you guessed it, just another role. Whether an object is considered to be a class, an instance, or both is up to how it is used and how you're thinking of it.
With few exceptions, any object can be used as a class or an instance. You can, for example, make an object that you think of as an instance of a class, then turn around and use that instance as the 'class' for another object.
Think of class_instance as a relationship between two objects. The essential aspect of the relationship is that the instance inherits from the class. The easiest way to understand objects and their inheritance is to know something about their implementation.
An object is just a collection of fields. A field has a key and a value. Any object can be a value; any object can be a key. Usually field keys are strings, but they can be integers (as in the case of vector objects and string objects) or any other kind of objects as when you're making an object-to-object map commonly implemented with hash tables in other languages.
You can get field values, set field values, add and remove fields, get all the keys of an object and find out which key has a particular object as its value.
Each object has a field whose key is "_parent". When you 'lookup' the value of a field, if the object you lookup in doesn't have the supplied key, the object from the _parent field is looked in for the supplied key. This lookup process goes up the _parent chain until it finds a field with that key or reaches the root object without finding that key and thereby errors. This process is called inheritance.
'thing' is the name of on object that can hold anything and is globally available.
thing.<set smell="good"/>
thing.smell
"good"

Below we make an instance of thing that will contain two fields, a field with key 'smell' that has the value "bad" and a field with key '_parent' that has the value thing.
<thing smell="bad"/>.smell"bad"
<thing smell="bad"/>._parentthing

is_a just means that the parent or grandparent or some ancestor of the subject is the first arg to is_a.
<thing smell="bad"/>.<is_a thing/>
true

Below we make an instance of thing and use THAT as the parent of another instance.
<<thing smell="bad"/>/>._parent._parent.<is thing/>
true
Example: smell is looked up and found in the parent of our instance.
<<thing smell="bad"/>/>.smell"bad"
Example: smell is looked up and found in the parent of our instance.
<<thing smell="bad"/>/>._parent.smell
"bad"
Example: bypass the low field of smell and get it out of thing itself.
<<thing smell="bad"/>/>._parent._parent.smell
"good"

Just as we can 'get' the parent of an object using the same mechanism for getting the value of any field, we can also 'set' the parent of any object using the same mechanism for setting the value of any field. You should know that it is unusual to change the parent of an object after it has been created, but at times it comes in extremely handy. This is a powerful feature of Water that few languages have. If you're having a hard time imagining when this could be useful, suppose you are modeling family relationships and a kid is adopted. Here's an example:
<set dad=<thing is_rich=true/>/>
<set kid=<thing/>/> <!-- kid created with 'thing' as its parent. But as
                        everyone knows, 'thing' is a lousy parent -->
kid.<set _parent=dad/>
kid.is_rich
true

Now with an understanding of the relationship of objects through inheritance, we introduce the method named 'class'. class makes a new object.

a wob
Parameter keyDefault valueType
_name"class"string
The first parameter to class is the name of the class.

Example: name a _name field in the new object.
<class vehicle/>._name"vehicle"

a wob
Parameter keyDefault valueType
"_parent"false
Each class has a 'superclass' or '_parent'. If you don't specify the parent (such as what we've done above), the _parent is wob, the root Water OBject.

<class vehicle/>._parentwob


We can specify the parent by extending the name with a "prefix" path. In this case, the parent of our new class is the non-last parts of the name of the call.
<class vehicle.boat/>._parentvehicle

The actual _name of the new class is the last part of the first argument of the call.
<class vehicle.boat/>._name"boat"

There's another way to specify the parent of a class, by passing in a _parent argument.
<class bike _parent=thing/>
thing.bike._parent
thing

In the parent of a class, a field is created whose key is the name of the new object and whose value is the new object. The default for the parent is wob, the root Water object. A call to class returns the new object.
Example: set a field in the parent, wob
<class vehicle/>
wob.vehicle
vehicle

a wob
Parameter keyDefault valueType
_save_expression_callfalse
Rarely will you need this functionality but it comes in handy if you are writing code that needs to write code or need a flexible syntax.
When you call a class with some keyword args to make an instance, you cannot normally find out the order that those args were passed to the method. In fact you can't find out a variety of things like whether they were passed as keywords or by position.
By defining the class with a "param" of _save_expression_call=true, it will not be a real param, but will instead bind the expression of the call to the local variable of _expression_call when the body of the make method is being executed.

<class boat x=2 _save_expression_call=true>
    <method make>
       ._expression_call
    </method>
</class>
<boat x=5/>.<is_a expression.call/>
true

What good is this? You can inspect the result of <boat x=5/> above, but here's some ideas:

Subclasses


If you call class in the content area of another call to class, the outer new object becomes the parent of the inner new one. All three of the following do the same thing.
<class vehicle>
    <class boat/>
</class>
<class vehicle/>
<class vehicle.boat/>
<class vehicle/>
vehicle.<set boat=<vehicle/>/>
vehicle.boat.<set _name="boat"/>

We can refer to the outer class as wob.vehicle or just vehicle for short. we can refer to the inner class as wob.vehicle.boat or vehicle.boat for short.
You can also give a class fields.
These fields are passed in exactly like you make parameters in a call to method. But instead of making method parameters, they just become fields of the new class.
<class vehicle wheels=true speed=true/>.wheels
true

Naturally, instances of our class inherit these fields.
<vehicle/>.wheelstrue

or they can "shadow" the class variables like so:
<vehicle wheels=false/>.wheels
false

Subclasses can shadow the class fields as well:
<class vehicle.boat wheels=false/>.wheels
false
vehicle.<boat/>.wheelsfalse

Class fields take the same characteristics as method parameters, a name, a default value, a type, and an execution kind. Think of creating an instance just like calling a method only instead of executing the body of the method, just make an instance that has all the passed-in fields.
vehicle.<boat wheels="usually not"/>.wheels
"usually not"

Make

Actually when you make an instance, a method IS called. It is the 'make' method of the class if any. The default just returns the new object. When the init method is called, the _subject local variable is bound to the new object. You can then do further initialization of the new object in the make method.
<class vehicle wheels=true>
   <method make>
      <if> .wheels.<is true/>
           .<set wheels="usually"/>
      </if>
      _subject
   </method>
 </class>
 <vehicle/>.wheels
"usually"

Notice that the last expression in the body of 'make' is _subject. That is because whatever is returned by the make method is retuned by the call to vehicle.
<class vehicle wheels=true>
  <method make>
    <if> .wheels.<is true/> _subject  
         else "wheelless"
    </if>
  </method>
</class>
<vehicle wheels="no"/>
"wheelless"

Think of the 'make' method as the constructor for the new object. It is just a method called with a _subject that is bound to a new object containing all the fields passed, with its parent being the 'container' of the 'make' method itself. Thus the default 'make' method is simply: <method make> _subject</>
Since 'make' returns the value of the last expression in its body that is executed (just like all methods), and that value is returned by a call to the container of make, you can have a call to a class return something other than an instance to the class. This is unusual, but certainly possible.
While the body of make is being executed, the local variable _subject_of_call is bound to the subject of the original call to making the instance.
Example: _subject_of_call
<class boat>
  <method make> _subject_of_call </>
</class>
13.<boat/>
13

Here's what's going on above: Our call 13.<boat/> looks up 'boat' in 13, doesn't find it, looks on up to wob before it finally finds the key "boat" with our class as its value. Then the method boat.make is called with a subject of the new instance of boat, and _subject_of_call bound to 13. Our make method just returns the value of _subject_of_call which is 13. _subject_of_call isn't used often, but can come in handy when the make method is trying to do something different based on the original subject to the call.
By placing a call to method in the content of a call to class, we not only make a method object, but we also create a field in the new class that has the name of the new method and the value of the new method.
<class vehicle>
  <method launch> "go"</>
</class>
vehicle.<launch/>
"go"

a wob
Parameter keyDefault valueType
contentfalse
The content of a call to class normally contains just calls to methods of that class. See the documetation om 'method' for how to define methods on a class outside of the body of their class.
If you want to make a subclass, you can stick a call to class in the content of a class call along with the methods for the class.

<class vehicle>
  <class boat>
    <method launch> "go" </method>
  </class>
  <method launch> "onward, James"</method>
</class>
vehicle

Above we've defined 2 classes each with a launch method.
vehicle.boatvehicle.boat
Example: use the class itself
vehicle.<launch/>"onward, James"
Example: make an instance and use that.
<vehicle/>.<launch/>"onward, James"
Example: use our subclass
vehicle.boat.<launch/>"go"
Example: make an instance of our subclass
vehicle.<boat/>.<launch/>"go"

Methods are objects and are stored in regular fields of their "containing" object which is usually an object created by class, but can be any object.
thing.<set drive=<method null> "on the road"</method> />
thing.<drive/>
"on the road"

Calling method with null gives it no name. But we don't care since it will usually be accessed from thing. Below we grab the method above via thing.drive, and make a synonym for it inside of the vehicle class named "cruise".
vehicle.<set cruise=thing.drive/>
<vehicle/>.<cruise/>
"on the road"

You can create methods for only certain instances of a class using 'set' or even set up the methods while making the instance.
<thing get_lost=<method null> "go jump in a lake"</method>/>.<get_lost/>
"go jump in a lake"

Above we create a new method via <method null> "go jump in a lake"</method>. that is used as the value of the "get_lost" field of the new instance of thing that we're creating with: <thing get_lost=<method null> "go jump in a lake"</method>/> Finally we're using that new instance of thing as the subject of a call to the "get_lost" method that we just created. this isn't the kind of code you'd write in practice but it is instructive to see how it all works.
Methods are objects, classes are objects, instances are objects and they all follow the same consistent rules.

_subject

When a call to 'class' is executed, its content is also executed. That's how the methods and subclasses get defined. You can also stick random code in the content of a class, though we don't recommend truely random code. It should be code that helps in the creation of the class. During the execution of a class call's content, the local variable _subject is bound to the new class being made. This lets you do extra initialization on the class or report about the creation.
<class foo>
  <echo "making new class: " _subject/>
</class>