# OTcl Tutorial (Version 0.96, September 95)

This tutorial is intended to start you programming in OTcl quickly, assuming you are already familiar with object-oriented programming. It omits many details of the language that can be found in the reference pages Objects in OTcl and Classes in OTcl. It also doesn't mention the C API or describe how to autoload classes.

## Comparison with C++

To the C++ programmer, object-oriented programming in OTcl may feel unfamiliar at first. Here are some of the differences to help you orient yourself.

- Instead of a single class declaration in C++, write multiple definitions in OTcl. Each method definition (with `instproc`) adds a method to a class. Each instance variable definition (with `set` or via `instvar` in a method body) adds an instance variable to an object.
- Instead of a constructor in C++, write an `init` instproc in OTcl. Instead of a destructor in C++, write a `destroy` instproc in OTcl. Unlike constructors and destructors, init and destroy methods do not combine with base classes automatically. They should be combined explicitly with `next`.
- Unlike C++, OTcl methods are always called through the object. The name `self`, which is equivalent to `this` in C++, may be used inside method bodies. Unlike C++, OTcl methods are always virtual.
- Instead of calling shadowed methods by naming the method explicitly as in C++, call them with `next`. `next` searches further up the inheritance graph to find shadowed methods automatically. It allows methods to be combined without naming dependencies.
- Avoid using static methods and variables, since there is no exact analogue in OTcl. Place shared variables on the class object and access them from methods by using `$class`. This behavior will then be inherited. For inherited methods on classes, program with meta-classes. If inheritance is not needed, use `proc` methods on the class object.

## Programming in OTcl

Suppose we need to work with many bagels in our application. We might start by creating a `Bagel` class.

>     % Class Bagel
>     Bagel

We can now create bagels and keep track of them using the `info` method.

>     % Bagel abagel
>     abagel
>     % abagel info class
>     Bagel
>     % Bagel info instances
>     abagel

Of course, bagels don't do much yet. They should remember whether they've been toasted. We can create and access an instance variable with the `set` method. All instance variables are public in the sense of C++. Again, the `info` method helps us keep track of things.

>     % abagel set toasted 0
>     0
>     % abagel info vars
>     toasted
>     % abagel set toasted
>     0

But we really want them to begin in an untoasted state to start with. We can achieve this by adding an `init` instproc to the `Bagel` class. Generally, whenever you want newly created objects to be initialized, you'll write an `init` instproc for their class.

>     % Bagel instproc init {args} {
>       $self set toasted 0
>       eval $self next $args
>     }
>     % Bagel bagel2
>     bagel2
>     % bagel2 info vars
>     toasted
>     % bagel2 set toasted
>     0

There are several things going on here. As part of creating objects, the system arranges for `init` to be called on them just after they are allocated. The `instproc` method added a method to the `Bagel` class for use by its instances. Since it is called init, the system found it and called it when a new bagel was created.

The body of the `init` instproc also has some interesting details. The call to `next` is typical for init methods, and has to do with combining all inherited init methods into an aggregate init. We'll discuss it more later. The variable called `self` is set when a method is invoked, and contains the name of the object on behalf of which it is running, or `bagel2` in this case. It's used to reach further methods on the object or inherited through the object's class, and is like `this` in C++. There are also two other special variables that you may be interested in, `proc` and `class`.

Our bagels now remember whether they've been toasted, except for the first one that was created before we wrote an init. Let's destroy it and start again.

>     % Bagel info instances
>     bagel2 abagel
>     % abagel destroy
>     % Bagel info instances
>     bagel2
>     % Bagel abagel
>     abagel

Now we're ready to add a method to bagels so that we can toast them. Methods stored on classes for use by their instances are called instprocs. They have an argument list and body like regular Tcl procs. Here's the toast instproc.

>     % Bagel instproc toast {} {
>       $self instvar toasted
>       incr toasted
>       if {$toasted>1} then {
>         error "something's burning!"
>       }
>       return {}
>     }
>     % Bagel info instprocs
>     init toast

Aside from setting the `toasted` variable, the body of the toast instproc demonstrates the `instvar` method. It is used to declare instance variables and bring them into local scope. The instance variable `toasted`, previously initialized with the `set` method, can now be manipulated through the local variable `toasted`.

We invoke the toast instproc on bagels in the same way we use the `info` and `destroy` instprocs that were provided by the system. That is, there is no distinction between user and system methods.

>     % abagel toast
>     % abagel toast
>     something's burning!

Now we can add spreads to the bagels and start tasting them. If we have bagels that aren't topped, as well as bagels that are, we may want to make toppable bagels a separate class. Let explore inheritance with these two classes, starting by making a new class `SpreadableBagel` that inherits from `Bagel`.

>     % Class SpreadableBagel -superclass Bagel
>     SpreadableBagel
>     % SpreadableBagel info superclass
>     Bagel
>     % SpreadableBagel info heritage
>     Bagel Object

More options on the `info` method let us determine that `SpreadableBagel` does indeed inherit from `Bagel`, and further that it also inherits from `Object`. `Object` embodies the basic functionality of all objects, from which new classes inherit by default. Thus `Bagel` inherits from `Object` directly (we didn't tell the system otherwise) while `SpreadableBagel` inherits from `Object` indirectly via `Bagel`.

The creation syntax, with its "-superclass", requires more explanation. First, you might be wondering why all methods except `create` are called by using their name after the object name, as the second argument. The answer is that `create` is called as part of the system's unknown mechanism if no other method can be found. This is done to provide the familiar widget-like creation syntax, but you may call `create` explicitly if you prefer.

Second, as part of object initialization, each pair of arguments is interpreted as a (dash-preceded) procedure name to invoke on the object with a corresponding argument. This initialization functionality is provided by the `init` instproc on the `Object` class, and is why the `Bagel` `init` instproc calls `next`. The following two code snippets are equivalent (except in terms of return value). The shorthand it what you use most of the time, the longhand explains the operation of the shorthand.

>     % Class SpreadableBagel
>     SpreadableBagel
>     % SpreadableBagel superclass Bagel

>     % Class create SpreadableBagel
>     SpreadableBagel
>     % SpreadableBagel superclass Bagel

>     % Class SpreadableBagel -superclass Bagel
>     SpreadableBagel

Once you understand this relationship, you will realize that there is nothing special about object creation. For example, you can add other options, such as one specifying the size of a bagel in bites.

>     % Bagel instproc size {n} {
>       $self set bites $n
>     }
>     % SpreadableBagel abagel -size 12
>     abagel
>     % abagel set bites
>     12

We need to add methods to spread toppings to `SpreadableBagel`, along with a list of current toppings. If we wish to always start with an empty list of toppings, we will also need an `init` instproc.

>     % SpreadableBagel instproc init {args} {
>       $self set toppings {}
>       eval $self next $args
>     }
>     % SpreadableBagel instproc spread {args} {
>       $self instvar toppings
>       set toppings [concat $toppings $args]
>       return $toppings
>     }

Now the use of `next` in the `init` method can be further explained. `SpreadableBagels` are also bagels, and need their `toasted` variable initialized to zero. The call to `next` arranges for the next method up the inheritance tree to be found and invoked. It provides functionality similar to call-next-method in CLOS.

In this case, the `init` instproc on the `Bagel` class is found and invoked. Eval is being used only to flatten the argument list in `args`. When `next` is called again in `Bagels` `init` instproc, the `init` method on `Object` is found and invoked. It interprets its arguments as pairs of procedure name and argument values, calling each in turn, and providing the option initialization functionality of all objects. Forgetting to call `next` in an `init` instproc would result in no option initializations.

Let's add a taste instproc to bagels, splitting its functionality between the two classes and combining it with `next`.

>     % Bagel instproc taste {} {
>       $self instvar toasted
>       if {$toasted == 0} then {
>         return raw!
>       } elseif {$toasted == 1} then {
>         return toasty
>       } else {
>         return burnt!
>       }
>     }

>     % SpreadableBagel instproc taste {} {
>       $self instvar toppings
>       set t [$self next]
>       foreach i $toppings {
>         lappend t $i
>       }
>       return $t
>     }

>     % SpreadableBagel abagel
>     abagel
>     % abagel toast
>     % abagel spread jam
>     jam
>     % abagel taste
>     toasty jam

Of course, along come sesame, onion, poppy, and a host of other bagels, requiring us to expand our scheme. We could keep track of flavor with an instance variable, but this may not be appropriate. Flavor is an innate property of the bagels, and one that can affect other behavior - you wouldn't put jam on an onion bagel, would you? Instead of making a class heirarchy, let's use multiple inheritance to make the flavor classes mixins that add a their taste independent trait to bagels or whatever other food they are mixed with.

>     % Class Sesame
>     Sesame
>     % Sesame instproc taste {} {
>       concat [$self next] "sesame"
>     }
>     % Class Onion
>     Onion
>     % Onion instproc taste {} {
>       concat [$self next] "onion"
>     }
>     % Class Poppy
>     Poppy
>     % Poppy instproc taste {} {
>       concat [$self next] "poppy"
>     }

Well, they don't appear to do much, but the use of `next` allows them to be freely mixed.

>     % Class SesameOnionBagel -superclass {Sesame Onion SpreadableBagel}
>     SesameOnionBagel
>     % SesameOnionBagel abagel -spread butter
>     % abagel taste
>     raw! butter onion sesame

For multiple inheritance, the system determines a linear inheritance ordering that respects all of the local superclass orderings. You can examine this ordering with an `info` option. `next` follows this ordering when it combines behavior.

>     % SesameOnionBagel info heritage
>     Sesame Onion SpreadableBagel Bagel Object

We can also combine our mixins with other classes, classes that need have nothing to do with bagels, leading to a family of chips.

>     % Class Chips
>     Chips
>     % Chips instproc taste {} {
>       return "crunchy"
>     }
>     % Class OnionChips -superclass {Onion Chips}
>     OnionChips
>     % OnionChips abag
>     abag
>     % abag taste
>     crunchy onion

## Other Directions

There are many other things we could do with bagels, but it's time to consult the reference pages. The OTcl language aims to provide you with the basic object-oriented programming features that you need for most tasks, while being extensible enough to allow you to customize existing features or create your own.

Here are several important areas that the tutorial hasn't discussed.

- There is support for autoloading libraries of classes and methods. See OTcl Autoloading for details.
- There is a C level interface (as defined by `otcl.h`) that allows new objects and classes to be created, and methods implemented in C to be added to objects. See OTcl C API for details.
- Classes are special kinds of objects, and have all of the properties of regular objects. Thus classes are a convenient repository for procedures and data that are shared by their instances. And the behavior of classes may be controlled by the standard inheritance mechanisms and the class `Class`.
- Methods called procs can be added to individual object, for sole use by that object. This allows particular objects to be hand-crafted, perhaps storing their associated procedures and data.
- User defined methods are treated in the same way as system provided methods (such as `set` and `info`). You can use the standard inheritance mechanisms to provide your own implementation in place of a system method.
- There are several other system methods that haven't been described. `array` gives information on array instance variables, `unset` removes instance variables, there are further info options, and so forth.