Simple OO in Pico Lisp

Pico Lisp has a very nice object system which will take some time to explore, let’s begin with simple examples and work towards more complex scenarios.

(class +Person)

(dm hello> ()
    (prin "hello"))
 
(hello> '+Person)

In this example we do not instantiate an object, in PHP the last call would correspond to Person::hello().

(class +Person)

(dm setHello> (HelloPhrase)
    (=: hello HelloPhrase))

(dm hello> ()
    (prin (: hello)))
    
(setHello> '+Person "Hello how are you?")

(hello> '+Person)

There are two shortcuts at work here, =: will put the contents of HelloPhrase into the member variable hello, : will in turn get it.

Let’s start creating instances:

(class +Person)

(dm T (Age Name)
    (=: age Age)
    (=: name Name))

(setq *John (new '(+Person) 65 'John))

(show *John)

So the first argument to new is a quoted list with the class we want to use. The constructor is the T method, that is a requirement, it always has to be called T for Pico to notice it correctly.

Add the above hello functions to the John code above and try:

(setHello> *John "Hello how are you?")

(hello> *John)

As you can see the result is the same, in this regard Pico is similar to PHP:

class Person{

  static $hello;
  
  function __construct($age, $name){
    $this->age = $age;
    $this->name = $name;
  }
  
  static function setHello($HelloPhrase){
    self::$hello = $HelloPhrase;
  }
  
  static function hello(){
    echo self::$hello;
  }
}

$john = new Person(65, "John");

$john->setHello("Hello how are you?");

$john->hello();

Person::hello();

The only difference is that PHP requires us to declare the $hello variable in order for it to be used in subsequent functions. A requirement which makes static usage less useful in PHP than in Pico.

Let’s see how we can fetch from and sort a list of persons:

(setq *Persons (list 
               (new '(+Person) 65 'John) 
               (new '(+Person) 38 'Fred)
               (new '(+Person) 41 'Annie) 
               (new '(+Person) 42 'Sam)))

This is actually how it could look after you get a list of people from a database which makes this example more useful than the stuff we did in the prior tutorial in this series.

(de assoc2d (Lst Key Value)
    (filter '((Sub)(= (get Sub Key) Value)) Lst))

(show (car (assoc2d *Persons 'name 'John)))

As you can see get can be used to get member variables in objects as well as by index as in the prior tutorial.

Sorting is similar to what we have already done in the prior part, in fact getSorting doesn’t have to be changed at all, neither does sort2d:

(de getCol (Lst K) 
    (mapcar '((Sub)(get Sub K)) Lst ) ) 

(de getSorting...

(de sort2d...

(show (car (sort2d *Persons 'name)))

Try removing the car in the last call, you will get a list looking something like ($34567855 $68904356 $21345679 $56854378). Show will only print their addresses when accessing objects indirectly as is the case here when they are in a list. I leave it as an exercise to write a function that loops through the list and shows each person.

Related Posts

Tags: ,