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

Re: "ocaml_beginners"::[] how can I use .cmo file for data structure persistence

Expand Messages
  • rixed
    It s hard to understand your problem ; you should show us a transcript of the command you run, their output, and what you were expecting. Anyway, if I
    Message 1 of 5 , Jun 27 10:24 PM
    • 0 Attachment
      It's hard to understand your problem ; you should show us a transcript of the
      command you run, their output, and what you were expecting. Anyway, if I
      understand correctly you can compile sprite.cmo, then run the top level, #load
      it, and then you get "undefined symbol" when you try to use it (or "unbound
      value"?). Undefined symbol is a gcc error, do you have a C library that you
      linked with your ocaml program ? What's the symbol name ? Have you opened Sprite
      before attempting to use it ?
    • Jeff Massung
      Jean, Reading your post, I gather you are doing one of two things when you load/compile your code: 1. Building the constant data on-the-fly as part of the
      Message 2 of 5 , Jun 29 10:37 AM
      • 0 Attachment
        Jean,

        Reading your post, I gather you are doing one of two things when you
        load/compile your code:

        1. Building the "constant" data on-the-fly as part of the compile step. For
        example:

        let sprite_hash = Hashtbl.create 100

        let my_sprite_1 = { ... }
        let my_sprite_2 = { ... }

        let _ =
        register_sprite_in_hashtbl "sprite_1" my_sprite_1;
        register_sprite_in_hashtbl "sprite_2" my_sprite_2

        If this is the case, then there's nothing for you to do. Yes, when you run
        it will re-run all the above code, but it will work at runtime in a final
        executable as well as loading. In OCaml there is no "main" function. All
        top-level forms are evaluated and if one of them happens to execute code
        (like a main function would), then so be it.

        2. You are creating a lot of data transformations given data off disk and
        don't want to re-run that code multiple times. You may not even want to
        ship the original source data. For example:

        let my_sprite_1 =
        let src_img = load_png ... in
        let transform = create_matrix ... in
        { img=src_img; transform=transform; ...}

        If this is the case, then what you may want to do is take a look at the
        Marshal module (
        http://caml.inria.fr/pub/docs/manual-ocaml/libref/Marshal.html) which will
        allow you to take my_sprite_1 and write it to memory and load it back,
        byte-for-byte. This will likely mean you have one program that cooks all
        your game data for you and another that will load it. The final cooked file
        will not be a "cmo" file, but you can Marshal it back in at runtime a lot
        faster than re-creating all of it from source data.

        If neither of those is your situation, then you need to provide some more
        information. ;-)

        Jeff M.

        On Thu, Jun 27, 2013 at 7:06 PM, Jean Saint-Remy <jeansaintremy@...>wrote:

        > **
        >
        >
        > Hi,
        >
        > I'm working on a game design, and I want to compile the game.ml file
        > together with sprite.ml file which contains all the data structures like
        > hash tables, arrays, and records which are fairly constant and do not
        > change. I have tried reading the manual and searched in the literature, but
        > didn't find any examples . The command is very straightforward. What I am
        > having trouble with is actually how to use a .cmo file which is loaded in
        > memory. When I try to access any of the data structures, I get error
        > undefined symbol. I used #load "sprite.cmo" which is fine and the
        > compilation is fine. Is there any tutorial that covers this subject in
        > depth?
        >
        > Regards,
        >
        > Jean
        >
        > [Non-text portions of this message have been removed]
        >
        >
        >


        [Non-text portions of this message have been removed]
      • Jean Saint-Remy
        Hi, Thank you for suggesting the Marshal module.  What I was having a problem with was a lack of documentation. Suppose for a minute that you have a large
        Message 3 of 5 , Jun 30 11:58 AM
        • 0 Attachment
          Hi,

          Thank you for suggesting the Marshal module. 

          What I was having a problem with was a lack of documentation. Suppose for a minute that you have a large data structure and you don't want to recreate it every time you are coding. We create and save a sample file
          (* persistent_strings.ml *)
          let tbl = [| "one"; "two"; "three"; "four"; "five"; |]

          We compile it with ocamlc -c persistent_strings.ml

          You will now have three files, persistent_strings.ml, persistent_strings.cmi, and persistent_strings.cmo.

          When you load ocaml persistent_strings.cmo (* ok *)
          the following code does not work

          for i=0 to 4; do
          Printf.printf "%s\n" (Array.get persistent_strings.tbl.( i );
          done ;;
          (* -: Unbound value persistent_strings *)

          But this one does

          for i=0 to 4; do
          Printf.printf "%s\n" (Array.get Persistent_strings.tbl.( i );
          done; 
          -:
          one
          two
          three
          four
          five

          If you happened to use a comma ',' instead of the semicolon ';' you only have a data structure with one element:  string * string * string * string * string * string, and ocaml is reporting an index out of bounds, but this is only a typo. An array is declared using a semicolon. The comma works also!

          I could not find any reference that explains the Capitalization part, of course this is intuitive if you read the section about modules. Intuitive how? Any code that is referencing your "persistent" data structure needs to be changed. A text editor apparently is required.

          With kind regards,

          Jean


          ________________________________
          From: Jeff Massung <massung@...>
          To: ocaml_beginners@yahoogroups.com
          Sent: Saturday, June 29, 2013 1:37 PM
          Subject: Re: "ocaml_beginners"::[] how can I use .cmo file for data structure persistence


          Jean,

          Reading your post, I gather you are doing one of two things when you
          load/compile your code:

          1. Building the "constant" data on-the-fly as part of the compile step. For
          example:

          let sprite_hash = Hashtbl.create 100

          let my_sprite_1 = { ... }
          let my_sprite_2 = { ... }

          let _ =
              register_sprite_in_hashtbl "sprite_1" my_sprite_1;
              register_sprite_in_hashtbl "sprite_2" my_sprite_2

          If this is the case, then there's nothing for you to do. Yes, when you run
          it will re-run all the above code, but it will work at runtime in a final
          executable as well as loading. In OCaml there is no "main" function. All
          top-level forms are evaluated and if one of them happens to execute code
          (like a main function would), then so be it.

          2. You are creating a lot of data transformations given data off disk and
          don't want to re-run that code multiple times. You may not even want to
          ship the original source data. For example:

          let my_sprite_1 =
              let src_img = load_png ... in
              let transform = create_matrix ... in
              { img=src_img; transform=transform; ...}

          If this is the case, then what you may want to do is take a look at the
          Marshal module (
          http://caml.inria.fr/pub/docs/manual-ocaml/libref/Marshal.html) which will
          allow you to take my_sprite_1 and write it to memory and load it back,
          byte-for-byte. This will likely mean you have one program that cooks all
          your game data for you and another that will load it. The final cooked file
          will not be a "cmo" file, but you can Marshal it back in at runtime a lot
          faster than re-creating all of it from source data.

          If neither of those is your situation, then you need to provide some more
          information. ;-)

          Jeff M.

          On Thu, Jun 27, 2013 at 7:06 PM, Jean Saint-Remy <jeansaintremy@...>wrote:

          > **
          >
          >
          > Hi,
          >
          > I'm working on a game design, and I want to compile the game.ml file
          > together with sprite.ml file which contains all the  data structures like
          > hash tables, arrays, and records which are fairly constant and do not
          > change. I have tried reading the manual and searched in the literature, but
          > didn't find any examples . The command is very straightforward. What I am
          > having trouble with is actually how to use a .cmo file which is loaded in
          > memory. When I try to access any of the data structures, I get error
          > undefined symbol. I used #load "sprite.cmo" which is fine and the
          > compilation is fine. Is there any tutorial that covers this subject in
          > depth?
          >
          > Regards,
          >
          > Jean
          >
          > [Non-text portions of this message have been removed]
          >

          >


          [Non-text portions of this message have been removed]



          ------------------------------------

          Archives up to December 31, 2011 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners
          The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
          Attachments are banned and you're asked to be polite, avoid flames etc.Yahoo! Groups Links



          [Non-text portions of this message have been removed]
        • Ashish Agarwal
          OCaml module names must start with a capital letter. When you compile a file foo.ml, you define a module Foo. Thus, in your example, persistent_strings.tbl is
          Message 4 of 5 , Jun 30 12:24 PM
          • 0 Attachment
            OCaml module names must start with a capital letter. When you compile a
            file foo.ml, you define a module Foo. Thus, in your example,
            persistent_strings.tbl is invalid. You must write Persistent_strings.tbl.

            Regarding the comma issue:

            ["one"; "two"] is an array of strings with two elements

            [("one", "two")] is an array of string pairs, there is 1 element in this
            array.

            ["one", "two"] is a shorthand for the above. OCaml allows omitting the
            parentheses around tuples under certain cases. Some would argue that this
            convenience is not worth it, and you should always be forced to write the
            parentheses.

            In the following case, it is somewhat nice that the parentheses can be
            omitted:

            ["one", "two";
            "three", "four"]

            You can avoid some clutter in defining an array of tuples. This is an array
            with 2 elements, each a pair of strings.


            On Sun, Jun 30, 2013 at 2:58 PM, Jean Saint-Remy <jeansaintremy@...>wrote:

            > **
            >
            >
            > Hi,
            >
            > Thank you for suggesting the Marshal module.
            >
            > What I was having a problem with was a lack of documentation. Suppose for
            > a minute that you have a large data structure and you don't want to
            > recreate it every time you are coding. We create and save a sample file
            > (* persistent_strings.ml *)
            > let tbl = [| "one"; "two"; "three"; "four"; "five"; |]
            >
            > We compile it with ocamlc -c persistent_strings.ml
            >
            > You will now have three files, persistent_strings.ml,
            > persistent_strings.cmi, and persistent_strings.cmo.
            >
            > When you load ocaml persistent_strings.cmo (* ok *)
            > the following code does not work
            >
            > for i=0 to 4; do
            > Printf.printf "%s\n" (Array.get persistent_strings.tbl.( i );
            > done ;;
            > (* -: Unbound value persistent_strings *)
            >
            > But this one does
            >
            > for i=0 to 4; do
            > Printf.printf "%s\n" (Array.get Persistent_strings.tbl.( i );
            > done;
            > -:
            > one
            > two
            > three
            > four
            > five
            >
            > If you happened to use a comma ',' instead of the semicolon ';' you only
            > have a data structure with one element: string * string * string * string
            > * string * string, and ocaml is reporting an index out of bounds, but this
            > is only a typo. An array is declared using a semicolon. The comma works
            > also!
            >
            > I could not find any reference that explains the Capitalization part, of
            > course this is intuitive if you read the section about modules. Intuitive
            > how? Any code that is referencing your "persistent" data structure needs to
            > be changed. A text editor apparently is required.
            >
            > With kind regards,
            >
            > Jean
            >
            > ________________________________
            > From: Jeff Massung <massung@...>
            > To: ocaml_beginners@yahoogroups.com
            > Sent: Saturday, June 29, 2013 1:37 PM
            > Subject: Re: "ocaml_beginners"::[] how can I use .cmo file for data
            > structure persistence
            >
            >
            >
            > Jean,
            >
            > Reading your post, I gather you are doing one of two things when you
            > load/compile your code:
            >
            > 1. Building the "constant" data on-the-fly as part of the compile step. For
            > example:
            >
            > let sprite_hash = Hashtbl.create 100
            >
            > let my_sprite_1 = { ... }
            > let my_sprite_2 = { ... }
            >
            > let _ =
            > register_sprite_in_hashtbl "sprite_1" my_sprite_1;
            > register_sprite_in_hashtbl "sprite_2" my_sprite_2
            >
            > If this is the case, then there's nothing for you to do. Yes, when you run
            > it will re-run all the above code, but it will work at runtime in a final
            > executable as well as loading. In OCaml there is no "main" function. All
            > top-level forms are evaluated and if one of them happens to execute code
            > (like a main function would), then so be it.
            >
            > 2. You are creating a lot of data transformations given data off disk and
            > don't want to re-run that code multiple times. You may not even want to
            > ship the original source data. For example:
            >
            > let my_sprite_1 =
            > let src_img = load_png ... in
            > let transform = create_matrix ... in
            > { img=src_img; transform=transform; ...}
            >
            > If this is the case, then what you may want to do is take a look at the
            > Marshal module (
            > http://caml.inria.fr/pub/docs/manual-ocaml/libref/Marshal.html) which will
            > allow you to take my_sprite_1 and write it to memory and load it back,
            > byte-for-byte. This will likely mean you have one program that cooks all
            > your game data for you and another that will load it. The final cooked file
            > will not be a "cmo" file, but you can Marshal it back in at runtime a lot
            > faster than re-creating all of it from source data.
            >
            > If neither of those is your situation, then you need to provide some more
            > information. ;-)
            >
            > Jeff M.
            >
            > On Thu, Jun 27, 2013 at 7:06 PM, Jean Saint-Remy <jeansaintremy@...
            > >wrote:
            >
            > > **
            > >
            > >
            > > Hi,
            > >
            > > I'm working on a game design, and I want to compile the game.ml file
            > > together with sprite.ml file which contains all the data structures
            > like
            > > hash tables, arrays, and records which are fairly constant and do not
            > > change. I have tried reading the manual and searched in the literature,
            > but
            > > didn't find any examples . The command is very straightforward. What I am
            > > having trouble with is actually how to use a .cmo file which is loaded in
            > > memory. When I try to access any of the data structures, I get error
            > > undefined symbol. I used #load "sprite.cmo" which is fine and the
            > > compilation is fine. Is there any tutorial that covers this subject in
            > > depth?
            > >
            > > Regards,
            > >
            > > Jean
            > >
            > > [Non-text portions of this message have been removed]
            > >
            > >
            > >
            >
            > [Non-text portions of this message have been removed]
            >
            > ------------------------------------
            >
            > Archives up to December 31, 2011 are also downloadable at
            > http://www.connettivo.net/cntprojects/ocaml_beginners
            > The archives of the very official ocaml list (the seniors' one) can be
            > found at http://caml.inria.fr
            > Attachments are banned and you're asked to be polite, avoid flames
            > etc.Yahoo! Groups Links
            >
            > [Non-text portions of this message have been removed]
            >
            >
            >


            [Non-text portions of this message have been removed]
          Your message has been successfully submitted and would be delivered to recipients shortly.