[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Bruce Hoult <bruce@h...> |
| Subject: | Re: [Caml-list] RFC: get/set vs get/ref |
At 11:49 AM +1000 7/12/01, John Max Skaller wrote:
>The difference is exemplified by the following techniques
>for incrementing a character:
>
> s.set ((s.get(pos) + 1),pos) // get/set method
> s.ref(pos).++ // ref method
>
>Clearly, ref methods are more powerful and more efficient,
I don't think that warrants a "clearly". Given good compilers *both*
will be compiled down to a memory load, an add, and a memory store.
For example, in Dylan you can do the following (Dylan source,
followed by C generated by the Gwydion d2c compiler, followed by PPC
asm):
---------------------------------
module: getset
define class <foo> (<object>)
slot x :: <integer>,
required-init-keyword: x:
end;
define function bar(s :: <foo>) => ()
s.x := s.x + 1
end function bar;
---------------------------------
#define SLOT(ptr, type, offset) (*(type *)((char *)ptr + offset))
void getsetZgetsetZbar_FUN(descriptor_t *orig_sp, heapptr_t A_s /* s */)
{
descriptor_t *cluster_0_top;
long L_x; /* x */
L_x = SLOT(A_s, long, 4);
SLOT(A_s, long, 4) = (L_x + 1);
return;
}
---------------------------------
0x29f4 <getsetZgetsetZbar_FUN>: lwz r9,4(r4)
0x29f8 <getsetZgetsetZbar_FUN+4>: addi r9,r9,1
0x29fc <getsetZgetsetZbar_FUN+8>: stw r9,4(r4)
0x2a00 <getsetZgetsetZbar_FUN+12>: blr
---------------------------------
>but on the other hand they expose the underlying implementation
>and prevent hooking changes to the mutable state.
Right. For example, in Dylan you can modify the above example to the
following (Dylan source, generated C code for bar(), asm for bar(),
output):
---------------------------------
module: getset
define function report(a :: <foo>, b :: <integer>) => ()
format-out("slot x was %=, now %=\n", a.x, b);
end;
define class <foo> (<object>)
slot x :: <integer>,
required-init-keyword: x:,
setter: internal-update-x;
end;
define inline method x-setter(new :: <integer>, a :: <foo>)
report(a, new);
internal-update-x(new, a);
end;
define function bar(s :: <foo>) => ()
s.x := s.x + 1
end bar;
begin
let a = make(<foo>, x: 13);
bar(a);
end
---------------------------------
void getsetZgetsetZbar_FUN(descriptor_t *orig_sp, heapptr_t A_s /* s */)
{
descriptor_t *cluster_0_top;
long L_x; /* x */
long L_new_value; /* new-value */
L_x = SLOT(A_s, long, 4);
L_new_value = (L_x + 1);
getsetZgetsetZreport_FUN(orig_sp, A_s, L_new_value);
SLOT(A_s, long, 4) = L_new_value;
return;
}
---------------------------------
0x28bc <getsetZgetsetZbar_FUN>: mflr r0
0x28c0 <getsetZgetsetZbar_FUN+4>: stmw r28,-16(r1)
0x28c4 <getsetZgetsetZbar_FUN+8>: stw r0,8(r1)
0x28c8 <getsetZgetsetZbar_FUN+12>: stwu r1,-80(r1)
0x28cc <getsetZgetsetZbar_FUN+16>: mr r28,r4
0x28d0 <getsetZgetsetZbar_FUN+20>: lwz r29,4(r28)
0x28d4 <getsetZgetsetZbar_FUN+24>: addi r29,r29,1
0x28d8 <getsetZgetsetZbar_FUN+28>: mr r5,r29
0x28dc <getsetZgetsetZbar_FUN+32>: bl 0x2590
<getsetZgetsetZreport_FUN>
0x28e0 <getsetZgetsetZbar_FUN+36>: stw r29,4(r28)
0x28e4 <getsetZgetsetZbar_FUN+40>: lwz r0,88(r1)
0x28e8 <getsetZgetsetZbar_FUN+44>: addi r1,r1,80
0x28ec <getsetZgetsetZbar_FUN+48>: mtlr r0
0x28f0 <getsetZgetsetZbar_FUN+52>: lmw r28,-16(r1)
0x28f4 <getsetZgetsetZbar_FUN+56>: blr
---------------------------------
[localhost:~/programs/dylan/getset] bruce% ./getset
slot x was 13, now 14
---------------------------------
>What's the best technique?
get/set, I think.
With appropriate language support it can:
- have exactly the same syntax as traditional languages, with no ugly
function notation for things that users think of as fields
- compile down to the exact same code that would be generated by
languages such as C
- have the ability to transparently hook extra functionality such as
format changes, monitoring, filtering into the getter and/or setter
with no changes to the client code.
Sorry to post Caml-free stuff here :-(
-- Bruce
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr