Hi Ladislav,

you wrote:

>We have gained a lot. CF:
>
>>no-copying: same? get in a 'message get in b 'message
>==true
>>no-copying: same? get in a/message 'get-num get in b/message 'get-num
>==true

I see what you mean. I'd call it a bug ... When objects are inherited,
objects they contain should not be treated any different than other
datatypes. If all other datatypes are copied, they should be copied as
well. Inconsistencies and exceptions tend to become a source for bugs.

------------
if that feature weren't available, this approach would be still feasible,
but we would have to define a function DESCEND, which would copy all
attributes except for MESSAGES object, which it would leave untouched
----------

I do, however, appreciate this bug as a feature, because I like your
approach.

1. One thing that disturbs me, though, is that you have to include the
object in each function you create. Passing the object to the function
doesn't bother me because that is being handled by your message-passing
function. But implementing each function with an argument reserved for the
object, that's repetetive and tedious.

---------
There is an easy  remedy to this: define a function MAKEMETHOD (or
MAKEMESSAGE),
which handles the argument preparation like this:

makemethod: func [args body] [
    func [self [object!] parblk] join [set args parblk] body
    ]

---------

Of course this can be easily rectified by modifying the root object and the
! function:

root: make object! [
  methods: make object! [
    object: none
    get-var: func [] [  print object/var return object/var ]
  ]
]

!: func [object [object!] 'method parm ] [
  set in object/methods 'object object
  do get in object/methods method parm
]

>> o: make root [var: 1]
>>
>> ! o get-var []
1
== []
>>

2. The second thing that really bothers me is the stupid dummy parm and the
fact that multiple arguments have to be passed in a block, because the
function ! can't tell in advance whether the called function expects any
arguments, and if so how many.

Besides passing dummy values, when the called function does not process
them, the called function also has to require a dummy value it doesn't need
in order to consume the dummy value. If you forget to include the dummy
value in the functions interface, then a value that function returns is
lost and replaced by the dummy value, because the value the function !
evaluates to will be the dummy value that was not consumed:

>> result: ! o get-var []
1
== []
>> print result

>> type? result
== block!

That kind of bug is difficult to detect.

I'd rather be able to
a) use the full range of function features, including returning values and
-----
I think there is nothing wrong with RETURN in this approach
-----
b) not have to include a dummy argument in every function to consume the
dummy argument being passed to the function !.
-------
not that bad, it looks a bit C++ - like
-------
c) Be able to pass multiple values individually rather then in a block and
d) not have to extract values from the block they were passed in.

--------
easy, see MAKEMETHOD
--------

The only way I have so far figured out to do that is by removing !'s parm
and replacing !'s do by return. Instead of executing the function, ! now
returns it. It can be executed at the same level as the ! function call was
evaluated and therefore any remaining arguments at that level will be
consumed by the retrieved function, if it requires arguments. The ugly side
to this approach is that you now must enter do explicitly:

!: func [object [object!] 'method ] [
  set in object/methods 'object object
  return get in object/methods method
]

>> do ! o get-var
1
== 1

That's not pretty either. But given the limited choices, I prefer to
preserve REBOL's standard argument passing convention and avoid bugs by not
prescribing that dummy arguments be passed and consumed, when a function
does not need them.

3. Hiding root functions and variables is not addressed by the embedded
object mechanism you proposed. The words defined in the methods sub-object
can all be messed with. Using contexts would solve that problem. Do you
recall
a) whether the reported instability of indefinite extended local words in
contexts was detected in the current REBOL version (2.2)?
--------
yes, still there, some of my programs crashed,
try:

b: use [a] [a: 1 'a]
recycle
get b
--------
b) Was it reported as an error, and
-------
if I understood Gabriele correctly, he reported it
-------
b) what observations led to the conclusion that it is the garbage collector?

-------
see the code above. If you don't RECYCLE, everything is fine for a while...
-------
TIA,

Elan

-Ladislav

Reply via email to