Loading ...
Sorry, an error occurred while loading the content.

Question on arrays and subclasses/subtypes

Expand Messages
  • j baxter
    Hi All, I m trying to get a better understanding of ocaml and wonder how to accomplish the following. I ll express the question in pseudo-Java but I hope the
    Message 1 of 6 , Aug 5, 2004
    • 0 Attachment
      Hi All,
      I'm trying to get a better understanding
      of ocaml and wonder how to accomplish the
      following. I'll express the question in
      pseudo-Java but I hope the goal is clear.

      Suppose I have an array z of objects which
      are instances of a class called node. That is
      fine, but occasionally I need a node
      with more information. Let's call it an object
      of class richnode, where richnode extends node.
      I really want some of the objects in z to be
      richnodes, and the rest to be nodes. So
      I want to have two kinds of objects in the same
      array, but the objects are related.
      This works well in Java but I'm not sure
      how to accomplish the same in ocaml.

      Any suggestions would be appreciated!
      Cheers,
      John



      __________________________________
      Do you Yahoo!?
      New and Improved Yahoo! Mail - Send 10MB messages!
      http://promotions.yahoo.com/new_mail
    • Richard Jones
      ... Casting node - richnode CANNOT be done in OCaml, unlike in Java. The reason is for compile-time type safety. I think the recommended trick is to keep
      Message 2 of 6 , Aug 5, 2004
      • 0 Attachment
        On Thu, Aug 05, 2004 at 12:12:11PM -0700, j baxter wrote:
        > Hi All,
        > I'm trying to get a better understanding
        > of ocaml and wonder how to accomplish the
        > following. I'll express the question in
        > pseudo-Java but I hope the goal is clear.
        >
        > Suppose I have an array z of objects which
        > are instances of a class called node. That is
        > fine, but occasionally I need a node
        > with more information. Let's call it an object
        > of class richnode, where richnode extends node.
        > I really want some of the objects in z to be
        > richnodes, and the rest to be nodes. So
        > I want to have two kinds of objects in the same
        > array, but the objects are related.
        > This works well in Java but I'm not sure
        > how to accomplish the same in ocaml.

        Casting node -> richnode CANNOT be done in OCaml, unlike in Java. The
        reason is for compile-time type safety.

        I think the recommended trick is to keep around a hash of object IDs
        to richnode objects. This way, you can check if the node in your node
        list is actually a richnode (stored in the hash).

        Every object has a unique ID, found by calling Oo.id. When you add a
        richnode to the list, put the ID -> richnode mapping in the Hashtbl
        too. When you retrieve a node from the list, check if the ID exists
        in the Hashtbl. If so, then the value will be the richnode type,
        correctedly typed. If not, you know that what you've got is just a
        node, not a richnode.

        Rich.

        --
        Richard Jones. http://www.annexia.org/ http://www.j-london.com/
        Merjis Ltd. http://www.merjis.com/ - improving website return on investment
        MOD_CAML lets you run type-safe Objective CAML programs inside the Apache
        webserver. http://www.merjis.com/developers/mod_caml/
      • Brian Hurt
        ... The problem here is that Ocaml doesn t really allow for downcasts- casts from base classes to derived classes (going up, from derived classes to base
        Message 3 of 6 , Aug 5, 2004
        • 0 Attachment
          On Thu, 5 Aug 2004, j baxter wrote:

          > Hi All,
          > I'm trying to get a better understanding
          > of ocaml and wonder how to accomplish the
          > following. I'll express the question in
          > pseudo-Java but I hope the goal is clear.
          >
          > Suppose I have an array z of objects which
          > are instances of a class called node. That is
          > fine, but occasionally I need a node
          > with more information. Let's call it an object
          > of class richnode, where richnode extends node.
          > I really want some of the objects in z to be
          > richnodes, and the rest to be nodes. So
          > I want to have two kinds of objects in the same
          > array, but the objects are related.
          > This works well in Java but I'm not sure
          > how to accomplish the same in ocaml.

          The problem here is that Ocaml doesn't really allow for downcasts- casts
          from base classes to derived classes (going up, from derived classes to
          base classes, is OK). This is because Ocaml doesn't keep type information
          at runtime- when you're downcasting in Java, you're circumventing Java's
          static type checking and depending up Java's run time type checking.

          The solution is to use a variant type in your array. This basically adds
          the run time type information to the objects you're holding in the array.

          --
          "Usenet is like a herd of performing elephants with diarrhea -- massive,
          difficult to redirect, awe-inspiring, entertaining, and a source of
          mind-boggling amounts of excrement when you least expect it."
          - Gene Spafford
          Brian
        • Konstantin Ignatiev
          ... class point (x:float) (y:float) = let downcasting_error name = failwith ( downcasting to class ^ name ^ generated run-time error ) in object (self)
          Message 4 of 6 , Aug 5, 2004
          • 0 Attachment
            On Thu, 5 Aug 2004 15:52:39 -0500 (CDT), Brian Hurt <bhurt@...> wrote:

            > The problem here is that Ocaml doesn't really allow for downcasts- casts
            > from base classes to derived classes (going up, from derived classes to
            > base classes, is OK). This is because Ocaml doesn't keep type information
            > at runtime- when you're downcasting in Java, you're circumventing Java's
            > static type checking and depending up Java's run time type checking.
            >
            > The solution is to use a variant type in your array. This basically adds
            > the run time type information to the objects you're holding in the array.

            Hmm, what's wrong with this solution for downcasting:

            ------------ file begins -------------
            class point (x:float) (y:float) =
            let downcasting_error name =
            failwith ("downcasting to class '" ^ name ^ "' generated run-time error")
            in
            object (self)
            val x = x
            val y = y
            method get_xy = (x,y)
            method cast_colorpoint = (downcasting_error "colorpoint" : colorpoint)
            method cast_point3d = (downcasting_error "point3d" : point3d)
            end and
            (* class *) colorpoint x y (c:int) = object(self)
            inherit point x y
            val color = c
            method get_color = color
            method cast_colorpoint = (self :> colorpoint)
            end and
            (* class *) point3d x y (z:float) = object(self)
            inherit point x y
            val z = z
            method get_xyz = (x,y,z)
            method cast_point3d = (self :> point3d)
            end;;

            let print_xy l =
            List.iter
            (fun x ->
            let (x,y) = x#get_xy in
            Printf.printf "(x = %f; y = %f)\n" x y)
            l;;

            let print_color l =
            List.iter
            (fun x ->
            let c = x#cast_colorpoint#get_color in
            Printf.printf "color = %d\n" c)
            l;;


            let makecolorpoint x y c = ((new colorpoint x y c) :> point);;

            let lst = [(makecolorpoint 1. 2. 3); (makecolorpoint (-57.) 20. 10)];;

            let lst1 = (new point 2.3 (-4.0)) :: lst;;

            print_xy lst;;

            print_xy lst1;;

            print_color lst;;

            print_color lst1;;
            ------------ file ends --------------

            When compiled and run, it will print:

            x = 1.000000; y = 2.000000)
            (x = -57.000000; y = 20.000000)
            (x = 2.300000; y = -4.000000)
            (x = 1.000000; y = 2.000000)
            (x = -57.000000; y = 20.000000)
            color = 3
            color = 10
            Fatal error: exception Failure("downcasting to class 'colorpoint'
            generated run-time error")

            --
            Konstantin.
          • Martin Jambon
            ... Besides what has been said already, I would like to add that most of the time classes and objects are not the easy way to go with OCaml. Maybe your problem
            Message 5 of 6 , Aug 5, 2004
            • 0 Attachment
              On Thu, 5 Aug 2004, j baxter wrote:

              > Hi All,
              > I'm trying to get a better understanding
              > of ocaml and wonder how to accomplish the
              > following. I'll express the question in
              > pseudo-Java but I hope the goal is clear.
              >
              > Suppose I have an array z of objects which
              > are instances of a class called node. That is
              > fine, but occasionally I need a node
              > with more information. Let's call it an object
              > of class richnode, where richnode extends node.
              > I really want some of the objects in z to be
              > richnodes, and the rest to be nodes. So
              > I want to have two kinds of objects in the same
              > array, but the objects are related.

              Besides what has been said already, I would like to add that most of the
              time classes and objects are not the easy way to go with OCaml.
              Maybe your problem could be solved simply by using sum types (variant
              types):

              type any_node = Simple_node of node
              | Rich_node of richnode

              This is a heterogenous list of nodes and richnodes:

              [ Rich_node rich1; Simple_node node; Rich_node rich123 ]


              Martin
            • dogged001
              ... Thanks to all who replied, that helps! John
              Message 6 of 6 , Aug 6, 2004
              • 0 Attachment
                --- In ocaml_beginners@yahoogroups.com, Martin Jambon
                <martin_jambon@e...> wrote:
                > On Thu, 5 Aug 2004, j baxter wrote:
                >>...

                >
                > Besides what has been said already, I would like to add that most of the
                > time classes and objects are not the easy way to go with OCaml.
                > Maybe your problem could be solved simply by using sum types (variant
                > types):

                Thanks to all who replied, that helps!
                John
              Your message has been successfully submitted and would be delivered to recipients shortly.