caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] functional objects
@ 2002-10-19  0:54 james woodyatt
  2002-10-19 20:48 ` Didier Remy
  0 siblings, 1 reply; 6+ messages in thread
From: james woodyatt @ 2002-10-19  0:54 UTC (permalink / raw)
  To: The Trade

everyone--

Before I file a wish request for this, I'd like to spark a discussion 
about it.

I really like the functional object semantics in Ocaml.  I think 
they're way cool.  I'm having a great time exploring what I can do with 
them.  Nothing really mindblowing to show for it yet, but give me time.

Anyway, one of the things I find lacking is a way to call a subclass 
constructor in the copy constructor.  In other words, I'd like to have 
some way to do the following:

	(* class type with only public methods exposed *)
	class type foo = object method f: unit end

	(* class with private members *)
	class foo x : foo = object
	  val x: int = x
	  method f = ()
	end

	(* derived functional subclass (notice method g) *)
	class bar y = object
	  inherit foo 0
	  val y: int = y
	  method g a b = {< foo a; y = b >}
	end

What I want is for a superclass class to be able to expose an interface 
to subclasses for constructing copies with arguments.  Is this a bad 
idea?  Has it already been considered and rejected?  Just curious.


-- 
j h woodyatt <jhw@wetware.com>
markets are only free to the people who own them.

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


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

* Re: [Caml-list] functional objects
  2002-10-19  0:54 [Caml-list] functional objects james woodyatt
@ 2002-10-19 20:48 ` Didier Remy
  2002-10-21  4:10   ` james woodyatt
  0 siblings, 1 reply; 6+ messages in thread
From: Didier Remy @ 2002-10-19 20:48 UTC (permalink / raw)
  To: james woodyatt; +Cc: The Trade

> Anyway, one of the things I find lacking is a way to call a subclass 
> constructor in the copy constructor.  In other words, I'd like to have 
> some way to do the following:
> 
> 	(* class type with only public methods exposed *)
> 	class type foo = object method f: unit end
> 
> 	(* class with private members *)
> 	class foo x : foo = object
> 	  val x: int = x
> 	  method f = ()
> 	end
> 
> 	(* derived functional subclass (notice method g) *)
> 	class bar y = object
> 	  inherit foo 0
> 	  val y: int = y
> 	  method g a b = {< foo a; y = b >}
> 	end
> 
> What I want is for a superclass class to be able to expose an interface 
> to subclasses for constructing copies with arguments.  Is this a bad 
> idea?  Has it already been considered and rejected?  Just curious.

Would the following code makes you happy?

        (* class type with only public methods exposed,
           plus a private overriding method foo *)
        class type foo_ = 
          object ('a) method f : unit method private foo : int -> 'a end;;

        (* class with private members *)
        class foo x : foo_ = object
          val x: int = x
          private method foo a = {< x = a >}
          method f = ()
        end;;

        (* derived functional subclass (notice method g) *)
        class bar y = object
          inherit foo 0
          val y: int = y
          method g a b = {< y = b >} # foo a 
        end;;

Didier Rémy
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


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

* Re: [Caml-list] functional objects
  2002-10-19 20:48 ` Didier Remy
@ 2002-10-21  4:10   ` james woodyatt
  2002-10-21  6:55     ` Didier Remy
  0 siblings, 1 reply; 6+ messages in thread
From: james woodyatt @ 2002-10-21  4:10 UTC (permalink / raw)
  To: Didier.Remy; +Cc: The Trade

On Saturday, Oct 19, 2002, at 13:48 US/Pacific, Didier Remy wrote:
> [I wrote:]
>> What I want is for a superclass class to be able to expose an 
>> interface
>> to subclasses for constructing copies with arguments.  Is this a bad
>> idea?  Has it already been considered and rejected?  Just curious.
>
> Would the following code makes you happy?
> [...]
>         (* derived functional subclass (notice method g) *)
>         class bar y = object
>           inherit foo 0
>           val y: int = y
>           method g a b = {< y = b >} # foo a
>         end;;

What would that look like in the multiple inheritance case?


-- 
j h woodyatt <jhw@wetware.com>
markets are only free to the people who own them.

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


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

* Re: [Caml-list] functional objects
  2002-10-21  4:10   ` james woodyatt
@ 2002-10-21  6:55     ` Didier Remy
  2002-10-21 18:40       ` james woodyatt
  0 siblings, 1 reply; 6+ messages in thread
From: Didier Remy @ 2002-10-21  6:55 UTC (permalink / raw)
  To: james woodyatt; +Cc: The Trade

> What would that look like in the multiple inheritance case?

Why did you not ask this in the first place? (i.e. if you meant 
multiple inheritance, you should have provided an example with multiple
inheritance). 

Have you really tried this exercise yourself before asking for help?  The
pattern seemed simple enough so that its generalization was obvious.

Didier Rémy


    class ['a1] c1 (x1 : 'a1) = object
      val x1_ = x1
      method m1 = ()
      method c1 x1 = {< x1_ = x1 >}
    end;;

    class ['a2] c2 (x2 : 'a2) = object
      val x2_ = x2
      method m2 = ()
      method c2 x2 = {< x2_ = x2 >}
    end;;

    class ['a1,'a2, 'a3] c3 x1 x2 (x3 : 'a3) = object
      inherit ['a1] c1 x1
      inherit ['a2] c2 x2
      val x3_ = x3
      method m3 = ()
      method c3 x1 x2 x3 = ({< x3_ = x3 >} # c1 x1) # c2 x2
    end;;

(* Note that fields are overriden in the reverse order, which does not
matter since they are all disjoint. Should method c1 and c2 both override
the same parent field, then the order should be enforced, as follows: *)

    class ['a1,'a2, 'a3] c3 x1 x2 (x3 : 'a3) = object (self)
      inherit ['a1] c1 x1
      inherit ['a2] c2 x2
      val x3_ = x3
      method m3 = ()
      method private c3_ x3 = {< x3_ = x3 >} 
      method c3 x1 x2 x3 = ((self # c1 x1) # c2 x2) # c3_ x3
    end;;


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


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

* Re: [Caml-list] functional objects
  2002-10-21  6:55     ` Didier Remy
@ 2002-10-21 18:40       ` james woodyatt
  2002-10-22  8:42         ` Didier Remy
  0 siblings, 1 reply; 6+ messages in thread
From: james woodyatt @ 2002-10-21 18:40 UTC (permalink / raw)
  To: Didier.Remy; +Cc: The Trade

On Sunday, Oct 20, 2002, at 23:55 US/Pacific, Didier Remy wrote:
> [I wrote:]
>> What would that look like in the multiple inheritance case?
>
> Have you really tried this exercise yourself before asking for help?

I'm very sorry.  Sincere apologies.

I mistakenly assumed, since the documentation does not explicitly say 
that the inherit clause defines a constructor method named after the 
superclass, that your examples would not compile.  Surprisingly, they 
actually do in ocaml-3.06.  It's not the most pleasant syntax I could 
imagine, but I'm very pleased to see that it's already possible to do 
what I want.

I have a suspicion, though, that the implementation makes a lot of 
temporary copies in this process.  Is that so?

Oh, never mind.  I'll find out for myself.  Thanks for all your help.


-- 
j h woodyatt <jhw@wetware.com>
markets are only free to the people who own them.

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


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

* Re: [Caml-list] functional objects
  2002-10-21 18:40       ` james woodyatt
@ 2002-10-22  8:42         ` Didier Remy
  0 siblings, 0 replies; 6+ messages in thread
From: Didier Remy @ 2002-10-22  8:42 UTC (permalink / raw)
  To: james woodyatt; +Cc: The Trade

> I mistakenly assumed, since the documentation does not explicitly say 
> that the inherit clause defines a constructor method named after the 
> superclass, that your examples would not compile.  Surprisingly, they 
> actually do in ocaml-3.06.  

I do not see how you inferred that they should not compiled form the
observation that:

   > the documentation not explicitly say the inherit clause defines a
   > constructor method named after the superclass

No, it does not say so and this is not true: the inherit
clause (1) [behaves as if one] copies the code from the parent class (2) can
be aliased to access methods of the superclass.  But the inherit clause does
not define a constructor method.  In the examples I gave, the constructor was
always explicitly defined.

> I have a suspicion, though, that the implementation makes a lot of 
> temporary copies in this process.  Is that so?

Yes, it does indeed. But do you really mind?  At least not in these toy
examples. Unless you are using this construction in a kind of systematic
way, and have long chain of inheritance, adding fields one-by-one, I am not
sure that one extra copies will create a significant lost in performance.

Anyway,  an alternative solution is to use the class constructor (of the
class you are defining) to build a new object from scratch. 
However, the definition must be split in two definitions because class
definitions are not recursive. 

    (* more general class *)
    class bar_ constr x y = object (self)
      inherit foo x  (* allow non zero argument to foo *)
      val y: int = y
      method g (a: int) (b:int) : bar = constr a b
    end;;
    
    (* close the recursion and specialize x to 0 *)
    class bar y = bar_ (let rec c x y = new bar_ c x y in c) 0 y;;

The two solutions are quite different: here (solution 2), a call to g
creates a fresh object of class "bar" from scratch (running the class
initializers if any) while in the previous solution it would only override
(functional update) an existing object.

The two solutions differ with respect to inheritance.  In a subclass gnu of
g, method g will have type gnu with solution 1 but will still have type bar
with solution 2.

There is no better solution, it just depends on the context.

        Didier Rémy
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


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

end of thread, other threads:[~2002-10-22  8:40 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-10-19  0:54 [Caml-list] functional objects james woodyatt
2002-10-19 20:48 ` Didier Remy
2002-10-21  4:10   ` james woodyatt
2002-10-21  6:55     ` Didier Remy
2002-10-21 18:40       ` james woodyatt
2002-10-22  8:42         ` Didier Remy

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