As you know, REBOL is a prototype-based object language. The idea of prototype objects came to REBOL early in its development from the language Self (Ungar and Smith). (See Wikipedia: Prototype Based Languages)
REBOL is prototype-based because a defining principle of REBOL is that simple things must be simple. Protypes provide a quick and informal definition of objects. You can create a new object as simply as this:
obj1: make object! [name: "Bob" age: 27 city: "Ukiah"]
You can now make additional instances with:
obj2: make obj1 [name: "Ann"] ; (other values inherited)
So that's handy and nice, and it will remain a primary method for REBOL 3.0.
However, in REBOL 3.0, we have reached the crossroads because we will support a more formal definition of objects. For instance, if you want private fields, typed instance variables, embedded documentation, an intializer function, and other properties, you can specify them.
Of course, it is possible to make these features "live" within the existing prototype-based model of objects. The question is, are we really implementing a hidden class-based system as a by-product?
I ask this question of myself, daily. The enhancements seem class-based because the definitional part of an object spans all instances (by reference back to the definition). In addition, that definition is immutable (cannot be modified by the instances without creating a new definition itself).
Other factors become important as well. For instance, if you mold an object, do you get its definition block molded for all instances? If we allowed classes, would there be a way to mold an instance and refer to its class (and that's problematic because REBOL does not support such reverse value-to-word mappings, so a new namespace may be required for class names - violating one of the denotational semantic rule at the foundation of REBOL).
And, on top of all this, I've yet to mention the fact that REBOL 3.0 is likely to support object methods to make object function implementation more efficient (in memory usage). The implementing of methods in REBOL has always been considered difficult (mainly because there is no referential anchor for a group, a class, of objects -- they are prototypical and can be cloned from each other, not just a single parent). A class-based approach makes the implementation of methods much easier.
So, think about that a bit. You should know that the extensions to objects are critical to 3.0 because we need features like typed instance variables to implement ports, events, gobs, and other C-interfaceable structures.
What about custom datatypes instead of classes? :)
Gregg Irwin 17-Aug-2006 16:40
I think this requires more information about goals, and how things are expected to work from a user's perspective. e.g.
Is class! a new type of value?
When you MAKE an object from a class, what is cloned and what isn't? Or, rather, what is "static"/class data and what is instance data?
Can you MAKE a class! from an object!
What do FIRST, SECOND, and THIRD return for a class?
Are classes immutable? e.g. once yuo MAKE an object, can you change the class "definition", and what happens to objects made from that class if you do?
Carl Sassenrath 17-Aug-2006 20:31:45
Gabriele: I knew you would say that! Well... custom datatypes are on the list. But, custom datatypes have a strict set of predefined functions. I'm not sure if the two concepts can be merged.
Greg: those are qood questions. The issue is being pushed by design concerns. It's not really that I want to add classes. Sometimes the language sprouts a new branch, and you have to understand what forces are at play. That's the stage we're in right now.
Robert 18-Aug-2006 3:09:31
My, I'm thinking too simple here but anyway:
If you add the "class" concept, than I see it as a way to specify to-be-created objects in a more formal & stricter way. To narrow down what can be done.
In a dynamic language I would expect a hidden back-pointer to the source class and hence I can still use the prototype approach. Just copy/clone objects, or use them as prototype as you have shown.
If you mold such an object, I would expect that one time the class specification is molded and all molded objects now show the internal hidden back-pointer as well. Maybe using a dialect approach is a good idea for molding/loading.
To me such an enhancement is more a way that I have one more option for specifying what I want a class/object/context to be. But I might be wrong...
Petr 18-Aug-2006 6:52:17
Would you find anything like "multiple inheritance" an usefull concept here? Kind of 'union on objects:
my-obj: make [obj11 obj2] 
The qustion is, what would happen if obj1 and obj2 contained identical word/method names.
Gabriele 18-Aug-2006 7:52:09
Datatypes: Well, sure, but numbers do not support series operations and viceversa. So you never have a perfect overlap. Also, my point actually is, that it seems to me that you'd have for custom types the same problems you'd have for classes (do you mold the type definition with each value?). So I have the suspect they are actually the same thing, minus the "fixed interface" that custom types must have - ie a class is a "relaxed" custom type. So... instead of introducing a new concept (class), why don't we reuse a concept we already have (type) and just allow the interface to be relaxed for custom types?
Goldevil 18-Aug-2006 8:54:02
Multiple inheritance is useful for me :-)
Example : Merging a face object! with a custom objects allows me to add complex validation function inside a face.
a: layout [ myfield: text ""]
myvalidation: make object! [
isvalid?: does [
if data = "" [ return FALSE ]
myfield: make [ myfield myvalidation] 
>> print myfield/isvalid?
For identical words, I propose that the last object's words overwrite previous object's words.
About custom datatypes, I'm just writting a small "custom_datatypes" librairy wich use object!. My goal is to simplify complex data validation in my current project.
If I understand, Gabriele, you propose to make the inverse path : building class behaviour from custom datatypes. Right ?
Gabriele 19-Aug-2006 14:35:51
Goldevil: you can do what you want in R2 with myfield: make myfield myvalidation. About class, I just think that a class and a custom type are basically the same thing (if you want a type to behave like a series, it has to have a series interface; but not all types need to have a series interface - so in general types and classes are the same thing, and indeed class based languages use them as "types"). BTW, I did implement custom datatypes in R2, but my work is undocumented.
Goldevil 20-Aug-2006 11:19:26
Right Gabriele. It was so simple !
I understand better what you wrote.
If we can create new classes/objects as datatypes maybe it becomes possible to use it with functions for parameter validation and auto-documentation :
Maybe implementation is complex because type casting must be more dynamic. Rebol must check not only with list of usual datatypes but also with a custom list that can be changed dynamically.
A problem with class and datatypes is to keep a simple syntax. I still want to write/read a value to variable of a custom datatype as simple with an integer. Accessor functions must not be an obligation (but can still be useful)
>>a: make class! [ value: 0]
>>b: make a
To make a new datatype as a new class, I suppose that the programmer have to use specific variables and functions with specific names that allow Rebol to give the same interface as usual datatypes.
Set, Get, Print, Convert,...
If classes and datatypes are the same thing, this is very elegant. But then, maybe syntax becomes less elegant.
Pierre Johnson 25-Aug-2006 0:58:54
Class-based inheritance for REBOL? Why not just kill the product?
Class-based Aristotlean socialist thinking abounds in academic-based / near academic-based junk -- Java, C++, C#, Python.
REBOL is even better -- simplest, most rapid prototyping with prototypes.
Products don't exist in a vacuum. If you're not making them to win in a market, there's no point.
Lesson #1 find a viable, underserved market ... discover wants and what customers who become buyers are willing to pay ... orient your purpose to deliver the goods that match these wants
REBOL 3.0 should ONLY REFLECT THIS and specifically --
How can REBOL 3.0 provide the easiest, fastest platform for "Web 2.0" and beyond?
You should be thinking ... REBOL as a proxy engine for data fetching, manipulation and presentation into displays -- whether they're desktop GUIs, browsers, Yahoo-like widgets, Google-like gadgets, wireless advertising scrolling displays, etc.
You're wasting time Carl with non-relevant technical issues. This is what happens when you lack purpose. You have no direction.
Ladislav 25-Aug-2006 4:41:53
I liked the prototype-based way of doing objects in REBOL. On the other hand, the usage of classes for the above mentioned problem looks technically superior.
Ladislav 25-Aug-2006 4:48:37
Moreover, if you implement classes the way you described, you may have both alternatives available for every user to choose from.
Thomas 25-Aug-2006 9:31:08
Just because you can't have your way as a fascist dictator, it doesn't help throwing tantrums and attacking people whose ultimate goals you don't know. Carl is running a business and only he (and perhaps a select other few) know where he wants to take it.
There's a better chance of people listening if you don't spice up every post with attacks, nonsensical academic right wing nonsense and prejudice.
Pardon me, everyone. I just had to say it.
Carl Sassenrath 25-Aug-2006 11:37:35
As always, I am open to all ideas from all users. If you take the time to type a message here, I'll take the time to read and consider it.
On this specific issue, there is a lot to consider.
Pierre Johnson 25-Aug-2006 12:54:25
Educating Thomas ...
Business is "busy ness" -- compliance (and hopefully avoidance) of regulatory issues.
Hopefully, REBOL is a venture intended to earn an extremely high ROI relative to alternative uses for cash.
Persons can spend a lifetime intellectually masturbating about "theoretically correct" and "technically superior ways of doing things, but if you're revenues don't exceed expenses at least at a constant rate and that rate doesn't exceed return to cash on Tens (US 10-year T-Note), you're losing.
I've posted in other places:
1) Carl is brilliant
2) I like Carl
3) REBOL is brilliant, superior, cool, fun
4) the persons connected with REBOL constitute the insularity -- highly indoctrinated, horrifically immature "group-think" persons whose intellect hovers within the range of 10-15 years of maturation
REBOL doesn't need class, class inheritance mechanism ... that is a bad idea ... it'll kill the product
To grow the usage, adoption of REBOL and the ROI to Carl and his investors, REBOL users want easier, faster, better ways to leverage REBOL to write better, faster, easier products that leverage what is here, now, real ... Google API, Yahoo API ... and 100's of other application categories.
Maxim Olivier-Adlhoch 25-Aug-2006 15:37:31
Before this explodes.
Mr Johnson is an identified and recognised Troll on several other REBOL channels.
He is bright intellectually, but lacks some human-related skills needed for him to actually converse with human beings below his perfect moral point of views.
best thing is to read and try to understand what he is saying in-between the lines (and insults) and be enlightened by the often smart ideas he has.
but please do not respond. it just what he wants... a cause.
have a nice day.
Maxim Olivier-Adlhoch 25-Aug-2006 16:36:14
classes can already be implemented conceptually, in REBOL. I have found that implementing classes in rebol, really needs very little actual code.
Liquid, uses shared methods (like face/feel) as the class definition for ALL instances. only the instance data is directly within the instance (outer) object!. The only drawback is that all methods need to be called with the pointer to the instance as the first parameter. and you have a REBOL equivalent to class useage.
empiric testing has proven that this can be upwards of 20 times faster on allocation and 40 times (or better) memory efficient (depending on method/data ratio and complexity of object definition). 10MB vs 400MB
also, I can change the class definition of an instance on the fly, and polymorph, union, all the good stuff.
only a few hooks within the interpreter, and some pre-defined words to exist in the class definition, which the interpreter calls on obvious events, like construct and destroy would allow all of this already available mechanism to be useable with less coding ugliness.
Maxim Olivier-Adlhoch 25-Aug-2006 17:10:03
full example of above:
thing: make object! [
class: context [
init: func [
self/useless: copy 
collect: func [
append self/useless value
build: func [
instance: make base spec
if (in base/class 'init) [
something: build thing [label: 'test]
something/class/collect something "Do or don't. "
something/class/collect something "There is no try! "
Maxim Olivier-Adlhoch 25-Aug-2006 17:35:04
very little changes are needed in current interpretation to make this much more usable and achieve many of the goals needed:
when a class based prototype is detected, omit the need for "/class/" when refering to something within the class definition.
Add other class-handled interpreter hooks like destroy, access, (init in example).
And omit the need to supply the pointer to the instance when calling methods, in this example "something".
While we keep all REBOL strengths, prototyping of the class and instance, easy union of class, etc... object creation time and memory consumption drop drastically. the only thing which cannot be removed is the need to use self/ within the methods, cause words are no longer bound to instances, but the class itself.
the addition of simple data hiding to object! themselves (data not shown in molds, or accessible outside a context) would round up the changes needed for most class-based requests I can remeber.
and consider this, we can mutate and even replace the class definition by simply doing:
This makes instance and classes extremely powerfull allies. Neither depend on the other.
All of the current tricks still work. Like getting class specs is as easy as:
sorry for this long series of posts, I normally dont do this, but I thought its a good opportunity to get it all out and give an example to munge about.
Pierre Johnson 25-Aug-2006 18:20:06
" Mr Johnson is an identified and recognised Troll ... " <--- this is the exact kind of nonsense that highly indoctrinated, immature persons post.
Waging an ad hominem campaign against me
"... lacks some human-related skills needed for him to actually converse with human beings ... "
while trying to paint yourself as a 'good guy taking the high road' with covers like
"He is bright intellectually ..."
"...enlightened by the often smart ideas he has."
doesn't make you any less of a phony snake.
As I teach my 4 year old, 'Your action defines your acts and your acts define who you are'.
My posts are about the product REBOL and the flirtation with a major mistake Carl is contemplating.
Your posts are about attacking me because I am not you and part of your immature, indoctrinated, socialist, banal, wouldn't know what marketing, markets, finance, capital and real life is if it smacked you in the face lives.
What a waste of time. Stick to REBOL, please. Leave me out of your 'personal attack because I hate the truth' petty lives.
Brian Wisti 31-Aug-2006 16:44:53
For prototyping i stick with prototypes. But i see issues with performance on cellphones ("small" cpu/memory), and we want to run there. If we want objects, the typical ones must be smaller. Its possible the face/feel way, but that is clumsy. I want a way to ease that.
About how i have no clean idea, thats a designer issue. It should be efficient, and it should be easy to convert my prototype-based code to this class (or datatype?) one.
About mold wit classes, i would like support for "named references".
One way could be a context around eveything, like (is the code-formating still broken?):
probe load "context: [^/classes: context[cls: a class]^/data: [obj1: context[class: 'classes/cls]]]"
About that "new namespace"-problem, i dont get it yet..
But how about support for multiple namespaces in a module?
Because with vid-styles you have already an artificial namespace, which is IMHO a problem because modules cant have local styles.
If modules could have a rebol-namespace and a vid-namespace and something like
"get/as word 'vid" that could help. Could also be combined with jit-binding, where a module can have a 'draw-namespace too.
(I have not thougth that fully through, but like the idea.)
Also i have a (maybe silly) idea about refering to the class. What if functions get their call-path? Means if i call face/feel/engage, that function would get the path and could find the object from there, by dropping feel/engage and fetching 'face. More complicated, but could help with multiple inheritance (face/feel, face/access,..) and maybe errors and reflection: the function knows its current name. As i said, maybe silly..
Brian Wisti 1-Sep-2006 3:41:01
oops, my mistake. It was Ladislav who suggested posting that link.
Xave 9-Sep-2006 12:44:10
ok i m just a beginner in rebol since few time. I ve been and still astonished by its efficiency. At school, we had hours and hours of Java (long and painfull). What interest me in rebol is that i can do better and faster with it than java. I dont need another java and it will be uncool if rebol lose a part of its efficiency simply for being an OO langage. But will it be possible to have the advantages of OO languages: class with protected variables, saving memory mechanisms and all the rest and anyway having the possibility of writing "good old" rebol ? What will be the impact of class implementation on the rest of the langage ?
Anton Rolls 21-Oct-2006 21:11:08
"...if you mold an object, do you get its definition block molded for all instances?"
I would prefer not, I think that would just lead to lots of needless duplication.
"If we allowed classes, would there be a way to mold an instance and refer to its class [?]"
I say no. By defining classes, you are separating a new concept from objects. That's the problem, and it's the same problem we have now where the mold output has no way of indicating the unique identity of the molded object.
My first thought is if an instance object wants a reference to its class, the user should specifically set an attribute to refer to it. That way the object doesn't have to have a link to its class available (even though it has one, hidden). And if it does have one, it has an attribute named as the user wishes (by convention it would be 'class).
my-class: make class! 
obj-1: make-instance my-class [class: my-class] ; <- here 'class is available
obj-2: make-instance my-class  ; <- here it is not (hidden)
So molding either object would just show the object-specific stuff, not the class definition, but if that's wanted then the user can do this:
Anton Rolls 21-Oct-2006 21:13:33
Oh yes, custom datatypes seem higher priority to me too. :)
Maxim Olivier-Adlhoch 28-Oct-2006 18:48:33
just add member hiding and object accessors and we can build our own class engine, our own datatypes, everything will be in the hands of the users :-)
and it removes the complexity out it REBOL and the risk of taking a bad decision.
if I'd do it, I'dd add more capacity to the object! itself, and implement a default class! type set of accessors.
As I demonstrate above, we can already do classes, they are just not programatically appealing.
IMHO the accessors should include hooks for 'get 'set 'mold 'print 'help
this would even allow us to make dialected accessors. imagine a face variant which accepts VID-type spec block directly. and which molds back to the dialect.