caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Question: 'instanceof'-like like primitive in OCaml
@ 2001-04-04 13:03 Nobuyuki Tomizawa
  2001-04-05 18:15 ` Brian Rogoff
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Nobuyuki Tomizawa @ 2001-04-04 13:03 UTC (permalink / raw)
  To: caml-list

Dear all,

I'm a novice OCaml programmer and have a question about heterogeneous
list and "downward cast".

Here is a pseudo Java code (I have):

     class base {
     	void common() {...};
     }

     class derived1 extends base {
     }

     class derived2 extends base {
	void specific() {..};
     } 

and what I want to do are:

     * make the list which typed as "base list".
     * call `derived2#specific' method if the element in the list is
     an instance of 'derived2'.

But, OCaml seems not to have Java's `instanceof'-like primitive and/or
downward-cast primitive.

My solution is to use variant type for the list and identify the class
using pattern matching:

    type tag = Derived2 of d2 | DontCare of b;;

    let l = [ Derived2(new d2); DontCare(new d1 :> b)] in ...;;

But I feel this solution is awkward because we have to define variant
type for each classes I want to treat them as specific.

Could you please tell me more 'smart' answer or another way in OCaml
style?

Thanks in advance.

-- Nobuyuki
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


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

* Re: [Caml-list] Question: 'instanceof'-like like primitive in OCaml
  2001-04-04 13:03 [Caml-list] Question: 'instanceof'-like like primitive in OCaml Nobuyuki Tomizawa
@ 2001-04-05 18:15 ` Brian Rogoff
  2001-04-05 19:09 ` Didier Le Botlan
  2001-04-06  9:14 ` Gerd Stolpmann
  2 siblings, 0 replies; 4+ messages in thread
From: Brian Rogoff @ 2001-04-05 18:15 UTC (permalink / raw)
  To: Nobuyuki Tomizawa; +Cc: caml-list

On Wed, 4 Apr 2001, Nobuyuki Tomizawa wrote:
> Dear all,
> 
> I'm a novice OCaml programmer and have a question about heterogeneous
> list and "downward cast".

There are no downcasts in the OCaml object system. Someone posted a patch
which would allow it but if you want to use standard OCaml you have to
write code without it. It is bad OO style anyways, right? 

> and what I want to do are:
> 
>      * make the list which typed as "base list".
>      * call `derived2#specific' method if the element in the list is
>      an instance of 'derived2'.
> 
> But, OCaml seems not to have Java's `instanceof'-like primitive and/or
> downward-cast primitive.
> 
> My solution is to use variant type for the list and identify the class
> using pattern matching:
> 
>     type tag = Derived2 of d2 | DontCare of b;;
> 
>     let l = [ Derived2(new d2); DontCare(new d1 :> b)] in ...;;
> 
> But I feel this solution is awkward because we have to define variant
> type for each classes I want to treat them as specific.
> 
> Could you please tell me more 'smart' answer or another way in OCaml
> style?

Actually, what you have isn't too bad, and you have to use variants to
get the capability that you want. I do  something like the following to
get leaf and hier node object classes which can go on the same structure, 
maybe this is helpful to you. 

type ('a, 'b) node = Leaf_node of 'a | Hier_node of 'b
type ('a,'b) instance =
    CellRef of (Atom.t * ('a, 'b) node * placement)
  | CellArrayRef of (Atom.t * ('a, 'b) node * placement * colrow * ipoint * ipoint)

class virtual leaf_intf  =
  object
    method virtual full_view : (leaf_intf, hier_intf) node
    ...
  end
and virtual hier_intf =
  object
    inherit leaf_intf
    method virtual leaf_view : (leaf_intf, hier_intf) node
    method virtual insts : (leaf_intf, hier_intf) instance list
  end

where instances will look like 

class some_leaf  =
  object (self)
    inherit leaf_intf
    method full_view = Leaf_node (self :> leaf_intf)
  end

class some_hier = 
  object (self)
    inherit hier_intf
    method full_view = Hier_node (self :> hier_intf)
    method leaf_view = Leaf_node (self :> leaf_intf)
   ...
  end

In all honesty though, when you need to do this kind of thing a lot you
should consider writing the code using algebraic data types rather than 
classes. I think that people used to a mostly OO language should avoid the 
OO features until they are comfortable with the classic ML way. 
 
-- Brian


-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


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

* Re: [Caml-list] Question: 'instanceof'-like like primitive in OCaml
  2001-04-04 13:03 [Caml-list] Question: 'instanceof'-like like primitive in OCaml Nobuyuki Tomizawa
  2001-04-05 18:15 ` Brian Rogoff
@ 2001-04-05 19:09 ` Didier Le Botlan
  2001-04-06  9:14 ` Gerd Stolpmann
  2 siblings, 0 replies; 4+ messages in thread
From: Didier Le Botlan @ 2001-04-05 19:09 UTC (permalink / raw)
  To: Nobuyuki Tomizawa; +Cc: caml-list

Hello,

Because of strong typing, heterogeneous lists are not allowed (which is
actually good).

As far as I understand, what you need is 
 - some kind of "instanceof"
 - some kind of dynamic cast (depending on the result of "instanceof").

You have many ways to get instanceof :

For example you can declare a virtual method "instanceOfSpecific : bool"
in base class, and each subclass must define it. 

Dynamic cast is not possible here because a base object cannot be seen
as a "derived2" object in general.
You can declare a method "specific" which raises an exception (default
behaviour) and which is overriden in class "derived2" to do what
expected.

Thus, if you incorrectly call "specific" method on a "derived1" object,
an exception is raised. This corresponds somehow to an incorrect dynamic
cast in Java.

Finally, here is a short example :

class virtual base =
object
  method common x = x+1
  method virtual isSpecific : bool
    
  (* 'specific' returns a string. failwith is polymorph, we must help
type checker. *)
  method specific = ((failwith "specific is not defined !!!") : string)
end

class derived1 =
object
  inherit base
  method isSpecific = false
end
  
class derived2 message =
object
  inherit base
  method isSpecific = true
  method specific = "Hello " ^ message
end

let example =
  
  print_endline "Starting...";
  let obj1 = new derived1
  and obj2 = new derived2 "World"
  and obj3 = new derived2 "Folks" in
    
  let list = [ obj1 ; obj2 ; obj3; obj2 ; obj1 ] in
    
  let apply_specific obj =
    if obj#isSpecific then print_endline obj#specific
    else print_endline "No Specific"
  in
    
    List.iter apply_specific list

compile :
ocamlc -o exam exam.ml

and try...

Nobuyuki Tomizawa wrote:

> I'm a novice OCaml programmer and have a question about heterogeneous
> list and "downward cast".
> 
> Here is a pseudo Java code (I have):
> 
>      class base {
>         void common() {...};
>      }
> 
>      class derived1 extends base {
>      }
> 
>      class derived2 extends base {
>         void specific() {..};
>      }
> 
> and what I want to do are:
> 
>      * make the list which typed as "base list".
>      * call `derived2#specific' method if the element in the list is
>      an instance of 'derived2'.
> 
> But, OCaml seems not to have Java's `instanceof'-like primitive and/or
> downward-cast primitive.
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


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

* Re: [Caml-list] Question: 'instanceof'-like like primitive in OCaml
  2001-04-04 13:03 [Caml-list] Question: 'instanceof'-like like primitive in OCaml Nobuyuki Tomizawa
  2001-04-05 18:15 ` Brian Rogoff
  2001-04-05 19:09 ` Didier Le Botlan
@ 2001-04-06  9:14 ` Gerd Stolpmann
  2 siblings, 0 replies; 4+ messages in thread
From: Gerd Stolpmann @ 2001-04-06  9:14 UTC (permalink / raw)
  To: Nobuyuki Tomizawa, caml-list

On Wed, 04 Apr 2001, Nobuyuki Tomizawa wrote:
>Dear all,
>
>I'm a novice OCaml programmer and have a question about heterogeneous
>list and "downward cast".
>
>Here is a pseudo Java code (I have):
>
>     class base {
>     	void common() {...};
>     }
>
>     class derived1 extends base {
>     }
>
>     class derived2 extends base {
>	void specific() {..};
>     } 
>
>and what I want to do are:
>
>     * make the list which typed as "base list".
>     * call `derived2#specific' method if the element in the list is
>     an instance of 'derived2'.
>
>But, OCaml seems not to have Java's `instanceof'-like primitive and/or
>downward-cast primitive.

I do not know the real reasons why the language designers refused to add these
constructs. However, I know from OO literature that they are often considered
as bad style, because they encourage programmers to mix object oriented
and procedural elements.

In Java you really need downcasts because Java lacks parametric polymorphism. 
For example, to use Java's stack class, you typically first cast your
elements to Object (which is done implicitly), and when you want to get your
elements back, you must downcast them to the class they previously had.

In O'Caml, the container types like stack have a type parameter (such as 
int Stack.t or string Stack.t) so the compiler already knows the type of the
elements; no downcasts are necessary as in Java.

>My solution is to use variant type for the list and identify the class
>using pattern matching:
>
>    type tag = Derived2 of d2 | DontCare of b;;
>
>    let l = [ Derived2(new d2); DontCare(new d1 :> b)] in ...;;
>
>But I feel this solution is awkward because we have to define variant
>type for each classes I want to treat them as specific.
>
>Could you please tell me more 'smart' answer or another way in OCaml
>style?

The traditional OO style is what you want:

class virtual base = object
  method common = ...

  method virtual specific : unit -> unit
end

class derived1 = object
  inherit base

  method specific() = ()
end

class derived2 = object
  inherit base

  method specific() = your action
end

Now, simply call x#specific for _all_ elements x of the list.

Gerd
-- 
----------------------------------------------------------------------------
Gerd Stolpmann      Telefon: +49 6151 997705 (privat)
Viktoriastr. 100             
64293 Darmstadt     EMail:   gerd@gerd-stolpmann.de
Germany                     
----------------------------------------------------------------------------
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr


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

end of thread, other threads:[~2001-04-08 20:11 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-04-04 13:03 [Caml-list] Question: 'instanceof'-like like primitive in OCaml Nobuyuki Tomizawa
2001-04-05 18:15 ` Brian Rogoff
2001-04-05 19:09 ` Didier Le Botlan
2001-04-06  9:14 ` Gerd Stolpmann

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