Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Pierre Boulet <Pierre.Boulet@lifl.fr>
To: caml-list@inria.fr
Subject: strange behavior of the object type-checker
Date: 09 Sep 1999 18:34:19 +0200	[thread overview]
Message-ID: <vtuvh9khwms.fsf@gala.lifl.fr> (raw)

dear ocamllers,

I have finally decided to give a try to the object subsystem of ocaml
and I have stumbled on something very strange (for me, at least).

In the code I present below, after some parametric class creation, I
try to execute some method of an object. Three *successive* tries give
three *different* results: two different typing error messages and
finally success.

This code has been tested with ocaml 2.02 and the cvs version of
yesterday (8 sept.), ocaml 2.02+3. They give the same result.

My aim is to define a graph class which implements simple graph
algorithms such as depth first scanning. Anyway, here is the code.

class ['e] node g n0 =
  object (self)
    val mutable mark = true  (* a boolean to handle cycles *)
    method mark = mark
    method set_mark = mark <- true
    method unset_mark = mark <- false

    val mutable edges = ([] : 'e list)  (* outgoing edges *)
    method edges = edges
    method add_edge e = edges <- e::edges
    initializer g#add_node self  (* registration into the graph *)

    val n = n0              (* dummy printing *)
    method n = n
    method draw =
      Printf.printf "node: %i\n" n

    method iter fn fe =     (* depth first iteration *)
      if self#mark then
 	begin
	  fn self;
      	  self#unset_mark;
      	  List.iter (fun e -> e#iter fn fe) edges
      	end
  end;;

class ['n] edge g from_init towards_init =
  object (self)
    val mutable mark = true  (* a boolean to handle cycles *)
    method mark = mark
    method set_mark = mark <- true
    method unset_mark = mark <- false

    val from = (from_init : 'n)
    val towards = (towards_init : 'n)
    method from = from
    method towards = towards
    initializer g#add_edge self  (* registration into the graph *)
    initializer from#add_edge self  (* registration into the from node *)

    method draw =            (* dummy printing *)
      Printf.printf "edge: %i->%i\n" from#n towards#n

    method iter fn fe =      (* depth first iteration *)
      if self#mark then
 	begin
	  fe self;
      	  self#unset_mark;
	  towards#iter fn fe
  	end
  end;;

class ['n,'e] graph =
  object (self)
    val mutable nodes = ([] : 'n list)  (* list of nodes *)
    method nodes = nodes
    val mutable start_node = (None : 'n option)
    method start_node = start_node
    method set_start_node n = start_node <- Some n
    method add_node n =
      nodes <- n::nodes;
      match nodes with
	| [n] -> self#set_start_node n
	| _ -> ()

    val mutable edges = ([] : 'e list)  (* list of edges *)
    method edges = edges
    method add_edge e = edges <- e::edges

    method set_marks = 
      List.iter (fun n -> n#set_mark) nodes;
      List.iter (fun e -> e#set_mark) edges

    method iter (fn : 'n -> unit) (fe : 'e -> unit) = (* depth first iteration *)
      match start_node with
	| None -> failwith "set start node first"
	| Some n -> 
	    self#set_marks;
	    (n#iter fn fe : unit)
  end;;

let g = new graph;;
g#iter (fun n -> n#draw) (fun e -> e#draw);;
let n1 = new node g 1;;
g#iter (fun n -> n#draw) (fun e -> e#draw);;
(* until now, everything goes fine *)
let e11 = new edge g n1 n1;;
g#iter (fun n -> n#draw) (fun e -> e#draw);;
(* returns:
	Characters 17-18:
	This expression has type 'a edge node as 'a
	It has no method draw
*)	
g#iter (fun n -> n#draw) (fun e -> e#draw);;
(* returns:
	Characters 0-1:
	This expression has type
	  (('a edge as 'b) node as 'a, ('c node as 'd) edge as 'c) graph
	It has no method iter
*)	
g#iter (fun n -> n#draw) (fun e -> e#draw);;
(* returns as expected:
	node: 1
	edge: 1->1
	- : unit = ()
*)	

So what happens? It seems that adding an edge to the graph unsettles
the type checker...

any thought?

-- 
Pierre.




             reply	other threads:[~1999-09-09 16:41 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-09-09 16:34 Pierre Boulet [this message]
1999-09-09 19:43 ` Jerome Vouillon
1999-09-28 18:56   ` Can someone explain? skaller
1999-10-04  8:23     ` Pierre Weis
1999-10-04 22:57       ` skaller
1999-10-05  9:43         ` Jerome Vouillon
1999-10-05 19:35         ` Gerd Stolpmann
1999-10-06  9:42           ` skaller
1999-10-08  0:17           ` Problem of coercion in recursive class definitions Peter Schrammel
1999-10-05 21:42         ` Can someone explain? Lyn A Headley
1999-10-06 10:17           ` skaller

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=vtuvh9khwms.fsf@gala.lifl.fr \
    --to=pierre.boulet@lifl.fr \
    --cc=caml-list@inria.fr \
    /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