boxIn some previous article, I have simulated the Val keyword in Scala. My Ambition as Creator being growing with time, I wana now simulate a Whole Universe (not yet) Language System such as Java, C#, PHP, javascript … well that’s the start :). If you are interested in Ruby, another Fool (HostileFork) attempted to do so and named it Rubol.

Why try to create a class-based OOP language from a prototyped-base OOP language ? The reasons to do so are numerous like simulating an other language or use it as a model for building Semantic Layers for DSL or Code Generators, ORM Framework Tools, etc… only imagination is the limit.

As we have seen Rebol is a Prototype-based language like Javascript (see Gregory’s article: Rebol for Javascript Programmers). Furthermore Rebol has been designed for Homoiconicity (what? you don’t know what it means ? I explained it already here !) so that building code that can execute itself can be done by a child.

Contrary to traditional OOP with Class, in such an OOP model, there are only concrete objects created at Runtime. What if we want to have the same model programming as in traditional OOP ? For example I would be able to define a Class like this:

Class Person [
    FirstName: ""
    LastName: ""
    BirthDate: 1/1/0001
    Age: func[ DateCalc [date! unset!]
    ][
        if (not value? 'DateCalc) [DateCalc: Now/Date]
      DateCalc - BirthDate

    ]
]

so as to create several instances of Person like this:

John: new Person
Jane: new Person

Access to John members or methods are finally as usual:

John/FirstName: "John"
John/FirstName: "Doe"
John/BirthDate: 1/1/1925
;get John Age today
John/Age
;get John Age in 2000
John/Age 1/1/2000

So let’s create a Class function in Rebol’s Console:


Class: func[Class][
   Probe Class
]

If you try to test it this will throw an error:


>> class Person
** Script Error: Person has no value
** Near: class Person
>>

To be able to pass a word with no value, you have to do this rather :


Class: func['Class][
   Probe Class
]

Then there will be no complain any more:


>> class person
person
== person

We also need to pass the Body which defines the Class so let’s add a Block parameter:


Class: func['Class Body [block!]][
   Probe Class
   Probe Body
]

It works:


>> Class Person [FirstName: "John"]
Person
[FirstName: "John"]
== [FirstName: "John"]
>>

Let’s finalize our class function by implementing it (we use the set function which allows to assign a value to a kind of “pointer” variable):


Class: func['Class Body [block!]][
    Type: to-word Class
    set Type Make Object! Body
]

To test, just Copy and Paste the first Block of code in the article, wonderfully it will work:


>> Class Person [
[        FirstName: ""
[        LastName: ""
[        BirthDate: 1/1/0001
[        Age: func[ DateCalc [date! unset!]
[            ][
[                if (not value? 'DateCalc) [DateCalc: Now/Date]
[              DateCalc - BirthDate
[
[            ]
[    ]
>> Probe Person
make object! [
    FirstName: ""
    LastName: ""
    BirthDate: 1-Jan-0001
    Age: func [DateCalc [date! unset!]][
        if (not value? 'DateCalc) [DateCalc: Now/Date]
        DateCalc - BirthDate
    ]
]
>>

We now need the new function to be able to instantiate our class. This is a piece of cake:


new: func[Class [Object!] ][
    Make Class []
]

And of course you can test that it works:


>> probe John
make object! [
    FirstName: ""
    LastName: ""
    BirthDate: 1-Jan-0001
    Age: func [DateCalc [date! unset!]][
        if (not value? 'DateCalc) [DateCalc: Now/Date]
        DateCalc - BirthDate
    ]
]
>> Probe Jane
make object! [
    FirstName: ""
    LastName: ""
    BirthDate: 1-Jan-0001
    Age: func [DateCalc [date! unset!]][
        if (not value? 'DateCalc) [DateCalc: Now/Date]
        DateCalc - BirthDate
    ]
]
>>

Here’s the final code (don’t copy the header if you want to copy and paste in Console):


Rebol []

Class: func['Class Body [block!]][
    Type: to-word Class
    set Type Make Object! Body
]

new: func[Class [Object!] ][
    Make Class []
]

Is that all ? What about Constructors ? Well, that’ll be for a next article some day as it is much more challenging :)

Bookmark and Share