caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Hiding public methods/friends methods
@ 2002-01-22 17:26 Claudio Sacerdoti Coen
  2002-01-31  0:09 ` Jacques Garrigue
  0 siblings, 1 reply; 2+ messages in thread
From: Claudio Sacerdoti Coen @ 2002-01-22 17:26 UTC (permalink / raw)
  To: caml-list

 Hi,

 I would like to define a huge bunch of mutual recursive classes
 with "friends methods". (The code is automatically generated, so
 I don't mind very much an heavy coding style.)

 Of course, I can use the trick of abstracting the output type
 of all the friends methods in the signature of the module.
 Because I have lots of friends methods, though, the resulting
 .mli I get is quite confusing.

 Another solution is creating "proxy" objects (see the code below).
 But I fear the performance loss to be significant.

 Which solution is best (not withstanding performances) and why?
 (Or which is a much better solution I don't see ;-)

				Thanks in advance,
				      C.S.C.


(* This is the interface I would like to have. *)
module type MT =
 sig
  class type ct = object method get_c' : ct' method m : int end
  and ct' = object method get_c : ct method m' : int end
  class c : int -> ct
  class c' : int -> ct'
 end
;;
 
module M : MT =
 struct
  (* This is the implementation: obj and obj' are the two public methods
   * I want to hide.
   *)
  class _c (obj : int) =
   object
    method obj = obj
    method get_c' = new _c' obj
    method m = (new _c' obj)#obj'
   end
  and _c' obj =
   object
    method obj' = obj
    method get_c = new _c obj
    method m' = (new _c obj)#obj
   end

  (* Again the interface... *)
  class type ct =
   object
    method get_c' : ct'
    method m : int
   end
  and ct' =
   object
    method get_c : ct
    method m' : int
   end

  (* The two proxy objects *)
  class c obj =
   let o = new _c obj in
    object
     method get_c' = (o#get_c' : _c' :> ct')
     method m = o#m
    end

  class c' obj =
   let o = new _c' obj in
    object
     method get_c = (o#get_c : _c :> ct)
     method m' = o#m'
    end
 end
;;

-- 
----------------------------------------------------------------
Real name: Claudio Sacerdoti Coen
PhD Student in Computer Science at University of Bologna
E-mail: sacerdot@cs.unibo.it
http://caristudenti.cs.unibo.it/~sacerdot
----------------------------------------------------------------
-------------------
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


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [Caml-list] Hiding public methods/friends methods
  2002-01-22 17:26 [Caml-list] Hiding public methods/friends methods Claudio Sacerdoti Coen
@ 2002-01-31  0:09 ` Jacques Garrigue
  0 siblings, 0 replies; 2+ messages in thread
From: Jacques Garrigue @ 2002-01-31  0:09 UTC (permalink / raw)
  To: sacerdot; +Cc: caml-list

From: Claudio Sacerdoti Coen <sacerdot@cs.unibo.it>

>  I would like to define a huge bunch of mutual recursive classes
>  with "friends methods". (The code is automatically generated, so
>  I don't mind very much an heavy coding style.)
> 
>  Of course, I can use the trick of abstracting the output type
>  of all the friends methods in the signature of the module.
>  Because I have lots of friends methods, though, the resulting
>  .mli I get is quite confusing.
> 
>  Another solution is creating "proxy" objects (see the code below).
>  But I fear the performance loss to be significant.
> 
>  Which solution is best (not withstanding performances) and why?
>  (Or which is a much better solution I don't see ;-)

Both are not very satisfactory, for the reasons you presented.
There is a long standing discussion about the bad consequences of
friend classes in C++ also.

> (* This is the interface I would like to have. *)
> module type MT =
>  sig
>   class type ct = object method get_c' : ct' method m : int end
>   and ct' = object method get_c : ct method m' : int end
>   class c : int -> ct
>   class c' : int -> ct'
>  end
> ;;

What you should really think about is whether you need to inherit from
these classes or not.
If you do not need to inherit (which is often the case in practice),
then you can avoid the problem by exporting only constructors:

module type MT =
 sig
  class type ct = object method get_c' : ct' method m : int end
  and ct' = object method get_c : ct method m' : int end
  val new_c : int -> ct
  val new_c' : int -> ct'
 end

These constructors can be defined in the implementation by:
  let new_c x = (new c x : c :> ct)

If you need to extend these classes (without overriding methods), you
can still define proxies afterwards. Proxies allowing method
overriding are much harder to define anyway.

Cheers,

Jacques Garrigue
-------------------
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


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2002-01-31  1:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-01-22 17:26 [Caml-list] Hiding public methods/friends methods Claudio Sacerdoti Coen
2002-01-31  0:09 ` Jacques Garrigue

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).