caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* typing of a class
@ 2000-03-07 13:12 David Chemouil
  2000-03-08 19:00 ` John Prevost
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: David Chemouil @ 2000-03-07 13:12 UTC (permalink / raw)
  To: caml-list


Hi,


I've been using the OO features of Caml these past days, and soon
observed a behavior of the typing system that I don't understand. Here
is a simplified version of my problem:

# class a (arg : a -> b) = object(self)
    val ob = arg self
  end
  and b = object
  end;;

The instance variable self
cannot be accessed from the definition of another instance variable


I don't understand why it is forbidden for an object to pass itself to
another one (which is possible in Java or Eiffel for example). Could
someone explain me? Or is there a paper talking about this?


thanks,

dc


-- 
David Chemouil [mailto:chemouil@enseeiht.fr] [mobile: 06 84 16 26 65]

Laboratoire d'informatique et de mathématiques appliquées (IRIT-INPT)



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

* Re: typing of a class
  2000-03-07 13:12 typing of a class David Chemouil
@ 2000-03-08 19:00 ` John Prevost
  2000-03-09  0:52 ` Benoit Deboursetty
  2000-03-09 20:25 ` Didier Remy
  2 siblings, 0 replies; 6+ messages in thread
From: John Prevost @ 2000-03-08 19:00 UTC (permalink / raw)
  To: David Chemouil; +Cc: caml-list

David Chemouil <David.Chemouil@enseeiht.fr> writes:

> I've been using the OO features of Caml these past days, and soon
> observed a behavior of the typing system that I don't understand. Here
> is a simplified version of my problem:
> 
> # class a (arg : a -> b) = object(self)
>     val ob = arg self
>   end
>   and b = object
>   end;;
> 
> The instance variable self
> cannot be accessed from the definition of another instance variable

> I don't understand why it is forbidden for an object to pass itself to
> another one (which is possible in Java or Eiffel for example). Could
> someone explain me? Or is there a paper talking about this?

The problem is that you're using self during the initialization of the
object, not in a method of the object.  Since the object isn't yet
initialized, it can't be passed to functions.  If you use a method,
you're okay:

class a (arg : a -> b) =
  object (self)
    method ob = arg self
  end
and b =
  object
  end

John.



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

* Re: typing of a class
  2000-03-07 13:12 typing of a class David Chemouil
  2000-03-08 19:00 ` John Prevost
@ 2000-03-09  0:52 ` Benoit Deboursetty
  2000-03-09 20:25 ` Didier Remy
  2 siblings, 0 replies; 6+ messages in thread
From: Benoit Deboursetty @ 2000-03-09  0:52 UTC (permalink / raw)
  To: David Chemouil; +Cc: caml-list

> I've been using the OO features of Caml these past days, and soon
> observed a behavior of the typing system that I don't understand. Here
> is a simplified version of my problem:
> 
> # class a (arg : a -> b) = object(self)
>     val ob = arg self
>   end
>   and b = object
>   end;;
> 
> The instance variable self
> cannot be accessed from the definition of another instance variable
> 
> I don't understand why it is forbidden for an object to pass itself to
> another one (which is possible in Java or Eiffel for example). Could
> someone explain me? Or is there a paper talking about this?

Ce n'est pas parce que l'objet se passe à un autre qu'une erreur est
détectée... Mais parce que les variables d'instance ne peuvent pas se
faire récursivement référence.

Les variables d'instance sont celles qui sont propres à chaque instance de
l'objet. Elles sont construites, à l'exécution, les unes après les autres
dans un ordre non spécifié (sauf "self", qui est toujours la dernière, je
suppose...) Dans votre cas, "self" et "ob" sont des variables d'instance
de la classe a.

Par exemple, imaginez que le système soit au moment de construire la
première variable d'instance d'un objet, mais que pour la construire il
ait besoin des autres variables d'instance...

[J'ai l'impression que c'est le même genre de raison qui empêche (pour le
moment ?) d'avoir des dépendances cycliques entre modules et des
applications de fonctions dans les membres droits des "let rec" (et là
j'interroge l'équipe de caml...)]

Le problème apparaît si la fonction que vous passez en argument fait accès
aux méthodes de self. Modifions un peu votre exemple, en faisant
l'hypothèse que le compilateur accepte le code suivant :

# class a (arg : a -> int) = object (self)
    val ob = arg self
    method get_ob = ob
  end;;

# let bad_arg = fun x -> ignore (x#get_ob); 0;;

# let instance_of_a = new a bad_arg;;

Que se passe-t-il à la construction de l'instance "instance_of_a" ? En y
réfléchissant un tout petit peu, vous verrez très vite qu'il va forcément
y avoir un pointeur invalide déréférencé (dans "bad_arg", "x#get_ob").

---

It is not especially forbidden to an object to pass itself to another one.

The error message means that you cannot recursively nest instance variable
declarations. Instance variable means variable that are built with each
instance of an object; here, ob and self are instance variable (they are
different for each object). When you call "new", the instance variables 
are built one after the other in a non specified order (except that self
is always the last one I suppose). Suppose for example the runtime builds
the first instance variable, but that instance variable depends on other
instance variable that will only be built later. This is clearly a
safeness pitfall!

(I think it is the same kind of problem that leads to a difficulty in
recursively nesting modules and "right side of let rec" problems?)

Let me somewhat modify your example to show you more concretely the point
of the error and assume the compiler accept this:

# class a (arg : a -> int) = object (self)
    val ob = arg self
    method get_ob = ob
  end

# let bad_arg = fun x -> ignore (x#get_ob); 0;;

# let instance_of_a = new a bad_arg;;

If you only imagine the building of an instance of that object, you will
soon see that an invalid pointer is going to be dereferenced no matter
what is the runtime implementation.

Best regards,
Benoit de Boursetty.




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

* Re: typing of a class
  2000-03-07 13:12 typing of a class David Chemouil
  2000-03-08 19:00 ` John Prevost
  2000-03-09  0:52 ` Benoit Deboursetty
@ 2000-03-09 20:25 ` Didier Remy
  2000-03-10  8:33   ` Xavier Leroy
  2 siblings, 1 reply; 6+ messages in thread
From: Didier Remy @ 2000-03-09 20:25 UTC (permalink / raw)
  To: David Chemouil; +Cc: caml-list

David Chemouil <David.Chemouil@enseeiht.fr> writes:

> # class a (arg : a -> b) = object(self)
>     val ob = arg self
>   end
>   and b = object
>   end;;
> 
> The instance variable self
> cannot be accessed from the definition of another instance variable

> I don't understand why it is forbidden for an object to pass itself to
> another one

Indeed, this is unsafe, since the function arg could well try to access 
the field "ob" of self that you are currently trying to initialize (so this
is not done yet).

Consider, for instance, 

    class a = object (self) val ob = self#bad method bad = ob + 1 end;;

which is very similar to:

    type a = { ob : int; }
    let rec self = { ob = self.ob + 1; };;

>  (which is possible in Java or Eiffel for example). 

Yes, but unfortunately Java is not a reference. In particular, it
initializes all fields to meaningless default values (which will often
result in a dynamically-raised null-pointer exception).

        Didier



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

* Re: typing of a class
  2000-03-09 20:25 ` Didier Remy
@ 2000-03-10  8:33   ` Xavier Leroy
  2000-03-16 13:34     ` thierry BRAVIER
  0 siblings, 1 reply; 6+ messages in thread
From: Xavier Leroy @ 2000-03-10  8:33 UTC (permalink / raw)
  To: Didier Remy, David Chemouil; +Cc: caml-list

David Chemouil writes:
> > # class a (arg : a -> b) = object(self)
> >     val ob = arg self
> >   end
> >   and b = object
> >   end;;
> > The instance variable self
> > cannot be accessed from the definition of another instance variable
> > I don't understand why it is forbidden for an object to pass itself to
> > another one
> >  (which is possible in Java or Eiffel for example). 

You can write your example just like in Java, by 1- making the
instance variable mutable, and 2- using an option type to play the
role of Java's null pointers.  You'd get:

class a arg = object(self)
    val mutable ob = (None : b option)
    initializer ob <- Some(arg self)
  end;;

It's not pretty, but that's exactly what's going on "under the hood"
in the equivalent Java code.

- Xavier Leroy



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

* Re: typing of a class
  2000-03-10  8:33   ` Xavier Leroy
@ 2000-03-16 13:34     ` thierry BRAVIER
  0 siblings, 0 replies; 6+ messages in thread
From: thierry BRAVIER @ 2000-03-16 13:34 UTC (permalink / raw)
  To: caml-list

Dear ocamlers,

Xavier Leroy a écrit:

> You can write your example just like in Java, by 1- making the
> instance variable mutable, and 2- using an option type to play the
> role of Java's null pointers.  You'd get:
>
> class a arg = object(self)
>     val mutable ob = (None : b option)
>     initializer ob <- Some(arg self)
>   end;;
>
> It's not pretty, but that's exactly what's going on "under the hood"
> in the equivalent Java code.
>
> - Xavier Leroy

An alternative technique I often use is

let not_ready () = failwith "not ready"

class a arg  = object (self)
  val mutable ob = not_ready
  initializer let it = arg self in ob <- (fun () -> it)
  method private ob = ob ()
end

the advantage is that it is not necessary anymore to match ob with Some x;
the drawback is that 'ob' value must now be accessed as 'ob ()'.
A workaround is to introduce method ob and type 'self#ob'.

Of course, field ob must not be accessed during (arg self) computation :-(

Cheers.



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

end of thread, other threads:[~2000-03-17 10:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-03-07 13:12 typing of a class David Chemouil
2000-03-08 19:00 ` John Prevost
2000-03-09  0:52 ` Benoit Deboursetty
2000-03-09 20:25 ` Didier Remy
2000-03-10  8:33   ` Xavier Leroy
2000-03-16 13:34     ` thierry BRAVIER

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