caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
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


  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;
as well as URLs for NNTP newsgroup(s).