From: Bruce Hoult <bruce@hoult.org>
To: John Max Skaller <skaller@maxtal.com.au>,
boost@yahoogroups.com, caml-list@inria.fr
Subject: Re: [Caml-list] RFC: get/set vs get/ref
Date: Fri, 13 Jul 2001 22:10:11 -0500 [thread overview]
Message-ID: <a0510100ab7755a97db61@[128.135.229.34]> (raw)
In-Reply-To: <3B4D020D.4039A62F@maxtal.com.au>
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
next prev parent reply other threads:[~2001-07-14 3:11 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <Pine.LNX.4.33.0107110922490.1683-100000@localhost.localdomain>
[not found] ` <0107111558020P.12210@baxter>
[not found] ` <00a701c10a15$9b1db190$6701a8c0@abeast1.com>
2001-07-12 1:49 ` John Max Skaller
2001-07-14 3:10 ` Bruce Hoult [this message]
2001-07-14 8:52 ` William Chesters
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='a0510100ab7755a97db61@[128.135.229.34]' \
--to=bruce@hoult.org \
--cc=boost@yahoogroups.com \
--cc=caml-list@inria.fr \
--cc=skaller@maxtal.com.au \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox