[REBOL] Objects: Preventing Code Duplication Re:(11)

1999-12-06 Thread lmecir

Hi, Rebols,

Something like:

!: func [
object [object!]
'method [word!]
/local mth
] [
; let's skip error checking for clarity
mth: get in object/methods method
bind second :mth in object 'self
return :mth
]

;text skipped

a: make object! [
num: 1
methods: make object! [
sumnum: func [other number] [
switch number [
1 [self/num]
2 [ (do ! other sumnum self 1) + (do ! self sumnum other
1) ]
]
]
]
]

Actually it works exactly as I would expect it to. What did you expect your
expression

>[ (do ! other sumnum self 1) + (do ! self sumnum other 1) ]

would do? Could you explain?

TIA,

Elan


Ladislav>

Some results:

>> b: make a [num: num + 1]
>> do ! a sumnum b 1
== 1
>> do ! b sumnum a 1
== 2
>> do ! b sumnum a 2
== 2
>> do ! a sumnum b 2
== 4

I think its' OK for you to expect it. No problemo!

I would prefer:

;Function to create methods, adds the hidden SELF argument
makemethod: func [args body] [
func append copy [self] args body
]

;Function to call methods
!: func [self [object!]  'method [word!] param [block!]] [
do append reduce [in self/methods method self] param
]

;end of %methods.r

;now the example:
a: make object! [
num: 1
methods: make object! [
sumnum: makemethod [other number] [
switch number [
1 [self/num]
2 [ (! other sumnum [self 1]) + (! self sumnum [other 1])]
]
]
]
]
b: make a [num: num + 1]

>> ! a sumnum [b 1]
== 1
>> ! b sumnum [a 1]
== 2
>> ! a sumnum [b 2]
== 3
>> ! b sumnum [a 2]
== 3

The choice is your's,

but my vote is: (guess what?)

Ladislav



[REBOL] Objects: Preventing Code Duplication Re:(11)

1999-12-05 Thread icimjs

Hi Gabriele,

you wrote:
>Hello [EMAIL PROTECTED]!
>To create simpler methods, why not binding them to the right
>object at the right time?
>
>Something like:
>
>!: func [
>object [object!] 
>'method [word!]
>/local mth
>] [
>; let's skip error checking for clarity
>mth: get in object/methods method
>bind second :mth in object 'self
>return :mth
>]
>

A work of beauty. Simple and effective. Of the different approaches in this
thread (including mine, which your function comments on) this is definitely
my favorite. Your approach also simplifies the embedded method object to:

root: make object! [
  var: none
  methods: make object! [
get-var: func [] [ var ]
sumnum: func [other [object!] [ (do ! other get-var) + (self get-var) ]
  ]
]

No need for the member I called object. En passant, Gabriele, I am
surprised that 'bind actually does its job in this example. I have had
problems using bind sensibly. Somehow, I always manage to get bind to
complain that it cannot resolve one or the other thing.

Ladislav, I withdraw my proposed ! for Gabriele's. It avoids having to keep
in mind which object the word 'object will be bound to, which can become a
problem, if you use it thoughtlessly, as you documented. I think we should
agree on Gabriele's function and add a little error handling. 

Do you see any problems with it?

Elan





[REBOL] Objects: Preventing Code Duplication Re:(11)

1999-12-05 Thread lmecir

Ciao, Gabriele,

you wrote:

To create simpler methods, why not binding them to the right
object at the right time?

Something like:

!: func [
object [object!]
'method [word!]
/local mth
] [
; let's skip error checking for clarity
mth: get in object/methods method
bind second :mth in object 'self
return :mth
]

- a nice idea. The problem here is that this approach is static, i.e.
non-re-entrant, because it uses only static storage for object parameter,
namely the code block of method, so your code wouldn't work for something
like this too:

a: make object! [
num: 1
methods: make object! [
sumnum: func [other number] [
switch number [
1 [self/num]
2 [ (do ! other sumnum self 1) + (do ! self sumnum other
1) ]
]
]
]
]

Ladislav




Regards,
Gabriele.
--
o) .-^-. (--o
| Gabriele Santilli / /_/_\_\ \ Amiga Group Italia --- L'Aquila |
| GIESSE on IRC \ \-\_/-/ /  http://www.amyresource.it/AGI/ |
o) `-v-' (--o






[REBOL] Objects: Preventing Code Duplication Re:(11)

1999-12-04 Thread 70740 . 503

Is it possible to make a sound (like a beep) from REBOL?



[REBOL] Objects: Preventing Code Duplication Re:(11)

1999-12-03 Thread icimjs

Hi Ladislav, 
you wrote:
>-
>Of course, it works.
>But try to rewrite the code like this:
>
>sumnum: func [other [object!]] [ (do ! other  get-num) +
> (do ! self get-num)
>
>and see what happens
>---

Do you realize that REBOL supplies every object automatically with the word
self? So if you are referring to the following construct:

root: make object! [
  var: none
  methods: make object! [
object: none
get-num: func [] [ object/var ]
sumnum: func [other [object!]] [ (do ! other  get-num) +
 (do ! self get-num)
]

then in your example self is referring to the embedded object methods.
Methods does not contain a word called var, therefore the attempt to
retrieve var from the methods object cannot work. Just as retrieving the
value of the word elephant from the object root cannot work. There is no
word elephant defined in the object root. There is not word var defined in
the object methods. self/var in the methods context however tries to look
up var in whatever self evaluates to at that point, which is the "methods"
object. 

That's got nothing to do with re-entrancy! It's got nothing to do with the
way I implemented "!" . 

Look at it like this:

If I have the simple object:

object: make object! [var: 1]

and I then try to use the path notation:

object/elephant

then REBOL will report an error (as it will in the case you describe above
and for the same reasons). To quote the error object/elephant will cause in
this example as proof that the path notation doesn't work would be foolish,
don't you think?

Again, filled with suspense, awaiting your response,

Elan






[REBOL] Objects: Preventing Code Duplication Re:(11)

1999-12-03 Thread lmecir

Hi, Elan

you wrote:

Hi Ladislav,

I wrote:
(Oh,
>and if I concur with my conclusions, please, please make sure that it
>really does fail!)

Read: (Oh, and if YOU concur ... )
Am I being a little self-centered here? ;-)

Sorry,

Elan

-
I was so sure, it would fail I didn't test it and after the send I found out
that I should have switched the (! self ...) and (! other ...). I deserve
all you sent, no problem. Moreover, I didn't test it for the second time
either, because I was so sure...

But now, after your apologies, it's tested and guaranteed: If you switch the
things, you get the wrong result.

I think, I should apologize myself too. I was just too lazy to try and
thought, that it would be obvious...
-

Ladislav



[REBOL] Objects: Preventing Code Duplication Re:(11)

1999-12-03 Thread icimjs

Once again Hi Ladislav,

I believe I've figured ou why you think my function should have problems
with reentrancy.

You see that my function sets the object word of the methods object of the
object it is passed. Therefore, whatever ! is doing, it relies on the
expectation that the methods/object will have the same value it just set it
to, when ! continues. If ! is now evaulated again, with a different object
argument, then the first instance of ! will become confused because
methods/object has been changed by the second ! invocation.

The reason that *cannot* happen is because the second invocation of ! - as
in your previous example - is not evaluated until the first invoked ! has
already completed its execution.

That is because my version of ! does not evaluate the function it
retrieves. It just returns it! Since ! can never be called recursively,
there is no reentrancy problem. ! will definitely finish executing by the
time the function it retrieved is evaluated. Any modifications that
function may cause to methods/object is no longer relevant to the
successful execution of the first ! instance. Specifically, if the function
calls ! again ... even several times over, the same will continue to apply.
The first verion of ! already completed its execution, the second
invocation of ! will retrieve whatever function it is instructed to
retrieve and complete executing. Only then will the third invocation of !
occur, and when that invocation of ! modifies methods/object, the two first
invocations have already long ceased to execute. And so on.

Have I guessed correctly?

Continuing to suspensefully expect your response,

Elan