PicoLisp Explored: Object-Oriented Programming, Part 2
Tags: functional, picolisp, lisp, oop
Published: 2022-02-01 10:11:21

In the [previous post](https://picolisp-blog.hashnode.dev/picolisp-explored-object-oriented-programming-part-1), we showed how to define classes and their methods and properties in PicoLisp using the ``class`` and ``dm`` functions.

We have already created the classes ``+Shape`` and its two subclasses ``+Rectangle`` and ``+Circle`` with a few methods. You can find the code [here](https://gitlab.com/picolisp-blog/web-applications/-/blob/main/docs/shape.l) or in the previous post. As you might remember, per syntax convention class names start with a ``+`` and methods end with a ``>``.

---------------------------------

Now we will show how we can create objects from that classes and use them. Let's open our file with the class definitions and run it with: ``$ pil shape.l +`` (the ``+`` opens the debugger).

---------------------------------

### Let's create a rectangle object!

We can create a new object using the function ``new``. A rectangle object also has four properties, ``X Y DX DY`` that also need to be defined in the function call. For example, the code below defines a rectangle with width=30 and height=20, with the reference point (x,y) in (0,0).
 
```
(new '(+Rectangle) 0 0 30 20)
```
Let's set it to the variable ``R``. 

```
: (setq R (new '(+Rectangle) 0 0 30 20)) 
-> $134432824  
```
*The return value is a so-called "anonymous symbol". However, it's not so relevant for the moment, so we will not dig further into that now.* 

We can check ``R`` using  ``show``:
```
: (show R)
$134432824 (+Rectangle)                   # Show the rectangle
   dy 20
   dx 30
   y 0
   x 0
```

---------------------------------

### Use the methods

Now let's use the ``area>``  and ``perimeter>`` functions that we defined before. The syntax is pretty straightforward:

```
: (area> R)                               # Calculate area
-> 600

: (perimeter> R)                          # and perimeter
-> 100
```
Now let's move the origin:

```
: (move> R 10 5)                          # Move 10 right and 5 down
-> 5
: (show R)
$134432824 (+Rectangle)
   y 5                                    # Origin changed (0,0) -> (10,5)
   x 10
   dy 20
   dx 30
```

Note that although the method ``move>`` was not defined for the ``+Rectangle`` class, it's still available since it is inherited from the ``+Shape``superclass.

--------------------------

We can do the same also with the circle class. Since it is really identical, I will not write it here, but you can check it [in the source code of the tutorial]((https://gitlab.com/picolisp-blog/web-applications/-/blob/main/docs/shape.l).

--------------------------

### Applying list functions

The objects can be used like any other symbols. For example they can be grouped to lists and we can apply [list functions](https://picolisp-blog.hashnode.dev/60-picolisp-functions-you-should-know-6-lists-and-strings) on them.

As an example, let's group the rectangle ``R`` and the circle ``C`` to a list and create a new list with their respective areas by applying ``mapcar 'area>`` on them:

```
: (mapcar 'area> (list R C))
-> (600 2827)
```

Or we could move all list items by 10 items down and right. Let's do this with an anonymous function:

```
: (mapcar 'area> (list R C))              # Get list of areas
-> (600 2827)

: (mapc
   '((Shape) (move> Shape 10 10))         # Move all 10 right and down
   (list R C) )
-> 25
```

*``mapcar`` and ``mapc`` both apply a defined function to each element of a list. The difference is that ``mapcar`` returns the whole list while ``mapc`` rertuns only the result of the last evaluation. [Here](https://picolisp-blog.hashnode.dev/60-picolisp-functions-you-should-know-6-lists-and-string) you can find an overview over the most important string functions.*

------------------------

### Prefix Classes

Assume that we want to extend our shape system. From time to time, we need shapes that behave exactly like the ones above, but are tied to a fixed position. That is, they do not change their position even if they receive a ``move>`` message. 

One solution would be to modify the ``move>`` method in the ``+Shape`` class to a no-operation. But this would require to duplicate the whole shape hierarchy (e.g. by defining ``+FixedShape``, ``+FixedRectangle`` and so on).

The PicoLisp Way is the use of **Prefix Classes through multiple inheritance**. It uses the fact that searching for method definitions is a depth-first, left-to-right [search of the class tree](https://picolisp-blog.hashnode.dev/binary-tree-traversal-part-1). We define a prefix class: 

```
: (class +Fixed)
(dm move> (DX DY))  # A do-nothing method
```

Now let's define a **Fixed** Rectangle by adding the prefix class when we create the object:

```
: (setq R (new '(+Fixed +Rectangle) 0 0 30 20))    # '+Fixed' prefix class
-> $134432881
```

Now the rectangle will not move even if we apply the ``move>`` function:

```
: (move> R 10 5)                                   # Send 'move>' message
-> NIL

: (show R)
$134432881 (+Fixed +Rectangle)
   dy 20
   dx 30
   y 0                                             # Did not move!
   x 0
```

------------------------

Alternatively, it's also possible to define a new subclass ``+FixRect`` that inherits from both ``+Fixed`` and ``+Rectangle``:

```
: (class +FixRect +Fixed +Rectangle)
-> +FixRect
```

and then use it directly:

```
: (setq R (new '(+FixRect) 0 0 30 20))
-> $13455710
``` 
------------------------

### Internal Representation

In the PicoLisp Explored-series we always try to cover the internal representation of the data as well.

As you might know by now, PicoLisp has only three data types: [numbers, symbols and lists](https://picolisp-blog.hashnode.dev/concepts-and-data-types). Where do we find objects and classes in this model? Do we need to change it?

Of course not - objects as well as classes are both implemented as symbols. **In fact, there is no formal difference between objects and classes**; classes are more a conceptual design consideration in the head of the programmer than a physical reality. 

We will find many examples for class concepts in the next posts of the Web Application Tutorial.

------------------------
### Sources
- https://software-lab.de/doc/index.html  
- https://gitlab.com/picolisp-blog/web-applications/-/tree/main/docs