caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Constructeurs en O'Caml
@ 1996-10-09  9:25 Vyskocil Vladimir
  1996-10-09 10:26 ` Christian Boos
  0 siblings, 1 reply; 6+ messages in thread
From: Vyskocil Vladimir @ 1996-10-09  9:25 UTC (permalink / raw)
  To: caml-list



Bonjour,

Existe-t'il comme en C++ une fonction qui est appelee a la construction d'un 
objet (pas seulement pour initialiser des variables d'instances) ?


---
Vyskocil Vladimir
vvyskoci@sophia.inria.fr
http://www.inria.fr/safir/SAFIR/Vladimir.html






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

* Re: Constructeurs en O'Caml
  1996-10-09  9:25 Constructeurs en O'Caml Vyskocil Vladimir
@ 1996-10-09 10:26 ` Christian Boos
  1996-10-09 10:44   ` Vyskocil Vladimir
  0 siblings, 1 reply; 6+ messages in thread
From: Christian Boos @ 1996-10-09 10:26 UTC (permalink / raw)
  To: Vyskocil Vladimir; +Cc: caml-list


Vyskocil Vladimir writes:
 > Existe-t'il comme en C++ une fonction qui est appelee a la construction d'un
 > objet (pas seulement pour initialiser des variables d'instances) ?

No, there's nothing such a "constructor" method, but a way to circumvent this
is to do the job as a side effect, when initializing the members. See the fol-
lowing sample code :

  class my_class name =
    (* MEMBERS *)
  
    val n = 
      (* begin constructor *)
	  ...;
      (* end constructor *)
      name
  
    (* METHODS *)
    ... 
  end


I would suggest a clearer syntax for that, by the mean of anonymous members :

  val _ = (* constructor code *)

Of course, these members will not be real fields in the object instances, 
but just "fake" fields for the purpose of calling constructors. In that way,
you could have constructors for objects with no members.


-- Christian Boos





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

* Re: Constructeurs en O'Caml
  1996-10-09 10:26 ` Christian Boos
@ 1996-10-09 10:44   ` Vyskocil Vladimir
  1996-10-09 12:12     ` Christian Boos
  1996-10-10 15:30     ` Jerome Vouillon
  0 siblings, 2 replies; 6+ messages in thread
From: Vyskocil Vladimir @ 1996-10-09 10:44 UTC (permalink / raw)
  To: caml-list


> Vyskocil Vladimir writes:
>  > Existe-t'il comme en C++ une fonction qui est appelee a la construction d'un
>  > objet (pas seulement pour initialiser des variables d'instances) ?
> 
> No, there's nothing such a "constructor" method, but a way to circumvent this
> is to do the job as a side effect, when initializing the members. See the fol-
> lowing sample code :
> 
>   class my_class name =
>     (* MEMBERS *)
>   
>     val n = 
>       (* begin constructor *)
> 	  ...;
>       (* end constructor *)
>       name
>   
>     (* METHODS *)
>     ... 
>   end
> 

Yes, but such contructor can't call a object method because self is
bind only at execution ie I can't do the following :

class my_class name as self = 
     (* MEMBERS *)
   
     val n = 
       (* begin constructor *)
	self#init;
 	  ...;
       (* end constructor *)
       name
   
     (* METHODS *)
     method init =
     ... 
   end

-- 
Vyskocil Vladimir
vvyskoci@sophia.inria.fr
http://www.inria.fr/safir/SAFIR/Vladimir.html






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

* Re: Constructeurs en O'Caml
  1996-10-09 10:44   ` Vyskocil Vladimir
@ 1996-10-09 12:12     ` Christian Boos
  1996-10-10 15:30     ` Jerome Vouillon
  1 sibling, 0 replies; 6+ messages in thread
From: Christian Boos @ 1996-10-09 12:12 UTC (permalink / raw)
  To: Vyskocil Vladimir; +Cc: caml-list


Vyskocil Vladimir writes:
 > 
 > [ ... see my previous message]
 > 
 > Yes, but such contructor can't call a object method because self is
 > bind only at execution ie I can't do the following :
 >
 > [ ... ]

Agreed, this is because you're not allowed to send messages to a partially
constructed object.

Solutions may be:

1) the 'val _ = ...' I suggested should be evaluated after all others
member initializations. [self] can then be safely bound inside the right part.

Pro: the 'val _' is like any other val, i.e it contains code evaluated
     at object creation time.

Cons: the 'val _' is the only member where self is bound.


2) as you suggested it, a constructor method can do the job
 (either named [init] or [my_class], the later would recall C++ ...).

Pro: self is bound in the 'method init = ...' as it is for all methods.

Cons: the 'init' method is called at object creation time, and you should not
     be allowed to call it directly.


3) Any other idea ?


But for sure, constructors are an usefull idiom !

-- Christian Boos




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

* Re: Constructeurs en O'Caml
  1996-10-09 10:44   ` Vyskocil Vladimir
  1996-10-09 12:12     ` Christian Boos
@ 1996-10-10 15:30     ` Jerome Vouillon
  1996-10-23 13:01       ` Jacques GARRIGUE
  1 sibling, 1 reply; 6+ messages in thread
From: Jerome Vouillon @ 1996-10-10 15:30 UTC (permalink / raw)
  To: Vyskocil Vladimir; +Cc: caml-list



> Yes, but such contructor can't call a object method because self is
> bind only at execution ie I can't do the following :
> 
> class my_class name as self = 
>      (* MEMBERS *)
>    
>      val n = 
>        (* begin constructor *)
> 	self#init;
>  	  ...;
>        (* end constructor *)
>        name
>    
>      (* METHODS *)
>      method init =
>      ... 
>    end

At the moment, you have to write a wrapper around class constructor `new 
my_class':

    let new_my_class name =
      let obj = new my_class name in
      (* begin constructor *)
      self#init;
      ...;
      (* end constructor *)
      obj

But you have to do it again for any subclass of my_class.

I had kept object initialisation very simple (only initialization of 
instance variables) because I did not know exactly what was needed.
Here are the problems I see at the moment:
 (1) One cannot access self during object creation (for instance to
     create a double link to another object, or register the object).
 (2) Side-effects during creation must occurs during a variable
     initialization.
 (3) One cannot share any computation (for instance, one could want
     the value of two instance variables to depend on the result
     of a common computation).

For solving point (1) and (2), I think that a new class component
`initializer expr' should be added (yet another keyword...). These
expressions `expr' would be evaluated after the initialization of
instance variables (object creation would be a two-pass process: first
initialization of instance variables, then evaluation of `initializer'
bodies). This is cleaner than having anonymous instance variables
`val _ = ...' with a special semantics, or a constructor method. 

For point (3), I see two possible solutions, but I'm not sure
of which one is the best solution.

The first solution is to add yet another class component
`let x = expr in'. `let'-bound variables would be visible from
instance variable definitions, but not from method definitions. One
could also have a `let _ = expr' as an alternative to `initializer'
component for point (2). Here are a few examples:

    (* Point (3) *)
    class c f =
      let x0 = Unix.time () in
      val x = x0
      inherit a (f x0)
    end

    (* Point (2) *)
    let count = ref 0
    class c =
      let _ = incr count
    end

Pros: - Variables used during initialization and instance variables
        are clearly distinguished.
      - Easy to implement (this might not be a good argument)
Cons: - Still more complex scoping rules.

The second solution is to change the scoping rules for instance
variables. An instance variable would also be visible to instance
variables appearing next. The class parameters could also be
considered as a private instance variables and be visible in
methods. Instance variables only used during object initialization
(and that does not appears in any method) would be omitted from the
object. Some examples follows:

    (* Point (3) *)
    class c f =
      val x = Unix.time ()
      inherit a (f x)
    end

    (* Point (2) *)
    let count = ref 0
    class c =
      val _ = incr count
    end

    (* Class parameter used in a method *)
    class c x =
      method m = x
    end

Pros: - Simpler scoping rules.
      - A bit more compact (see third example).
Cons: - Which values appears in or are omitted from the object is not
        obvious to the user.
      - One must rely on some more or less clever compiler
        optimizations, so that instance variables not used in any
        method are omitted from the object (as a side-effect, the
        implementation is more complex).

-- Jerome Vouillon






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

* Re: Constructeurs en O'Caml
  1996-10-10 15:30     ` Jerome Vouillon
@ 1996-10-23 13:01       ` Jacques GARRIGUE
  0 siblings, 0 replies; 6+ messages in thread
From: Jacques GARRIGUE @ 1996-10-23 13:01 UTC (permalink / raw)
  To: caml-list


About problems of initialization of classes, Jerome Vouillon wrote:

   [..]

> The second solution is to change the scoping rules for instance
> variables. An instance variable would also be visible to instance
> variables appearing next. The class parameters could also be
> considered as a private instance variables and be visible in
> methods. Instance variables only used during object initialization
> (and that does not appears in any method) would be omitted from the
> object. Some examples follows:

>     (* Point (3) *)
>     class c f =
>	val x = Unix.time ()
>	inherit a (f x)
>     end

>     (* Point (2) *)
>     let count = ref 0
>     class c () =
>	val _ = incr count
>     end

>     (* Class parameter used in a method *)
>     class c x =
>	method m = x
>     end

> Pros: - Simpler scoping rules.
>	 - A bit more compact (see third example).
> Cons: - Which values appears in or are omitted from the object is not
>	   obvious to the user.
>	 - One must rely on some more or less clever compiler
>	   optimizations, so that instance variables not used in any
>	   method are omitted from the object (as a side-effect, the
>	   implementation is more complex).

This looks like a very good idea for me. In particular, the
impossibility to use parameters of the class in methods is rather hard 
to grasp to beginners, and this is solved by this approach.

On the other hand, I think the compiler should only omit unused
private variables. Then wether the optimization is really done or not
can be ignored by the user.

If you start omitting public ones, you will have strange cases were
the type of the class depends on this optimization. Actually you may
want to define non referenced instance variables in a class, just to
use them through inheritance (stange, but, why not ?).

I also take this occasion to say that I also like another idea
proposed on this forum, of changing the associativity of # (message
sending). This makes syntax closer to Smalltalk, which seems logical.
For the concurrence with O'Labl, or rather LablTk, which was evocated
in that message, I was aware of that, but I think this must be
restricted to real configuration commands. Creating a class without
real objects, just to create a function with optional parameters, is
possible, but doesn't seem very clean to me: the call syntax becomes
rather complex. And with a not-to-big number of arguments, optionals
are more efficient.

class search (s : string) as self =
  val string = s
  val mutable forward = true
  val mutable nocase = true
  method backward = forward <- false; self
  method exact = nocase <- false; self
  method go = search s forward nocase
end

new search "hello" #backward #go  --->  search "hello" false true

With optionals:

let search' s ?:forward [< true >] ?:nocase [< true >] =
    search s forward nocase

search' "hello" forward:false  --->  search "hello" false true

Still, this is an amusing technique, close to what is used in C.

Jacques
---------------------------------------------------------------------------
Jacques Garrigue	Kyoto University      garrigue@kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>





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

end of thread, other threads:[~1996-10-23 18:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1996-10-09  9:25 Constructeurs en O'Caml Vyskocil Vladimir
1996-10-09 10:26 ` Christian Boos
1996-10-09 10:44   ` Vyskocil Vladimir
1996-10-09 12:12     ` Christian Boos
1996-10-10 15:30     ` Jerome Vouillon
1996-10-23 13:01       ` 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).