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

Re: "ocaml_beginners"::[] Execution semantics

Expand Messages
  • Issac Trotts
    ... No, for example # let f1 x = x;; val f1 : a - a = # let f2 x = -x;; val f2 : int - int = # let example1 a b x = let a = f1 a in let b =
    Message 1 of 26 , Nov 3, 2004
    • 0 Attachment
      On Nov 3, 2004, at 11:03 AM, andrew cooke wrote:

      > Where can I find a clear description of how OCaml executes code. In
      > particular, I want to understand when functions with several values are
      > evaluated - is the evaluation progressive (during Currying) or is
      > evaluation delayed until all arguments are present.
      >
      > For example, are the following equivalent, always?
      >
      > let example1 a b x =
      > let a' = f1 a in
      > let b' = f2 b in
      > f3 a' b' x
      >
      > let example2 a b =
      > let a' = f1 a in
      > let b' = f2 b in
      > fun x -> f3 a' b' x
      >
      > let example3 x a b =
      > let a' = f1 a in
      > let b' = f2 b in
      > f3 a' b' x

      No, for example

      # let f1 x = x;;
      val f1 : 'a -> 'a = <fun>
      # let f2 x = -x;;
      val f2 : int -> int = <fun>
      # let example1 a b x =
      let a' = f1 a in
      let b' = f2 b in
      f3 a' b' x;;
      val example1 : 'a -> int -> 'b -> 'a * int * 'b = <fun>
      # let example2 a b =
      let a' = f1 a in
      let b' = f 2 b in
      fun x -> f3 a' b' x ;;
      val example2 : 'a -> int -> 'b -> 'a * int * 'b = <fun>
      # let example3 x a b =
      let a' = f1 a in
      let b' = f2 b in
      f3 a' b' x;;
      val example3 : 'a -> 'b -> int -> 'b * int * 'a = <fun>
      # example1 1 2 3;;
      - : int * int * int = (1, -2, 3)
      # example2 1 2 3;;
      - : int * int * int = (1, -2, 3)
      # example3 1 2 3;;
      - : int * int * int = (2, -3, 1)

      -----
      Issac Trotts
      Programmer, NIMH Human Brain Project
      University of California, Davis
      http://mallorn.ucdavis.edu/conexus
    • Seth J. Fogarty
      On Wed, 3 Nov 2004 16:03:20 -0300 (CLST), andrew cooke ... These two are equivalent. I have a question, however, for the list. Why does example2, when so
      Message 2 of 26 , Nov 3, 2004
      • 0 Attachment
        On Wed, 3 Nov 2004 16:03:20 -0300 (CLST), andrew cooke
        <andrew@...> wrote:
        >
        > Where can I find a clear description of how OCaml executes code. In
        > particular, I want to understand when functions with several values are
        > evaluated - is the evaluation progressive (during Currying) or is
        > evaluation delayed until all arguments are present.
        >
        > For example, are the following equivalent, always?
        >
        > let example1 a b x =
        > let a' = f1 a in
        > let b' = f2 b in
        > f3 a' b' x
        >
        > let example2 a b =
        > let a' = f1 a in
        > let b' = f2 b in
        > fun x -> f3 a' b' x

        These two are equivalent. I have a question, however, for the list.
        Why does example2, when so explicitly curried as such, have a '_a when
        curried?


        # let a = example2 1 2;;
        val a : '_a -> int * int * '_a = <fun>

        I know why example1 does this, I woul dhave thought example2 would not have.

        > let example3 x a b =
        > let a' = f1 a in
        > let b' = f2 b in
        > f3 a' b' x

        The order you pass the arguments in matters in OCaml, since the
        invoker has no names.

        example3 1 2 3
        binds 1 to x, 2 to a, and 3 to b.
        example1 1 2 3
        binds 1 to a, 2 to b, and 3 to x.

        > Thanks,
        > Andrew
        >
        > --
        > ` __ _ __ ___ ___| |_____ work web site:
        > http://www.ctio.noao.edu/~andrew
        > / _` / _/ _ \/ _ \ / / -_) personal web site: http://www.acooke.org/andrew
        > \__,_\__\___/\___/_\_\___| list: http://www.acooke.org/andrew/compute.html
        >
        >
        >
        > Archives up to September 30, 2004 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 Sponsor
        >
        > ADVERTISEMENT
        >
        >
        > ________________________________
        > Yahoo! Groups Links
        >
        > To visit your group on the web, go to:
        > http://groups.yahoo.com/group/ocaml_beginners/
        >
        > To unsubscribe from this group, send an email to:
        > ocaml_beginners-unsubscribe@yahoogroups.com
        >
        > Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.


        --
        Seth Fogarty sfogarty@[gmail.com|rice.edu|livejournal]
        Neep-neep at large AIM: Sorrath
        "I know there are people in this world who do not love their fellow
        human beings - and I hate people like that" --Tom Lehrer.
      • andrew cooke
        Thanks for the reply. Just to get this straight, because i think I wasn t anything like clear enough (I was not talking about function signatures, but about
        Message 3 of 26 , Nov 3, 2004
        • 0 Attachment
          Thanks for the reply.

          Just to get this straight, because i think I wasn't anything like clear
          enough (I was not talking about function signatures, but about when
          evaluation occurs), are you saying that for the first two examples:

          let f = exampleN 1 2 in
          ...
          let g = f 3

          most of the work (ie evaluating f1 and f2) *in both cases* is done before
          the dots? So, for example, if "let g = ..." was in a loop, only the
          minimum of work would be repeated.

          And for example3, where I was clearly way too brief (sorry), I was
          assuming that the answer to the above was "yes" and then considering

          let f = fun (x -> example3 x 1 2) in
          ...
          let g = f 3

          Again, if g was evaluated in a loop, would that be as efficient as
          examples 1 and 2?

          I hope that's a little clearer.

          Thanks,
          Andrew


          Seth J. Fogarty said:
          >
          > On Wed, 3 Nov 2004 16:03:20 -0300 (CLST), andrew cooke
          > <andrew@...> wrote:
          >>
          >> Where can I find a clear description of how OCaml executes code. In
          >> particular, I want to understand when functions with several values are
          >> evaluated - is the evaluation progressive (during Currying) or is
          >> evaluation delayed until all arguments are present.
          >>
          >> For example, are the following equivalent, always?
          >>
          >> let example1 a b x =
          >> let a' = f1 a in
          >> let b' = f2 b in
          >> f3 a' b' x
          >>
          >> let example2 a b =
          >> let a' = f1 a in
          >> let b' = f2 b in
          >> fun x -> f3 a' b' x
          >
          > These two are equivalent. I have a question, however, for the list.
          > Why does example2, when so explicitly curried as such, have a '_a when
          > curried?
          >
          >
          > # let a = example2 1 2;;
          > val a : '_a -> int * int * '_a = <fun>
          >
          > I know why example1 does this, I woul dhave thought example2 would not
          > have.
          >
          >> let example3 x a b =
          >> let a' = f1 a in
          >> let b' = f2 b in
          >> f3 a' b' x
          >
          > The order you pass the arguments in matters in OCaml, since the
          > invoker has no names.
          >
          > example3 1 2 3
          > binds 1 to x, 2 to a, and 3 to b.
          > example1 1 2 3
          > binds 1 to a, 2 to b, and 3 to x.
          >
          >> Thanks,
          >> Andrew
          >>
          >> --
          >> ` __ _ __ ___ ___| |_____ work web site:
          >> http://www.ctio.noao.edu/~andrew
          >> / _` / _/ _ \/ _ \ / / -_) personal web site:
          >> http://www.acooke.org/andrew
          >> \__,_\__\___/\___/_\_\___| list:
          >> http://www.acooke.org/andrew/compute.html
          >>
          >>
          >>
          >> Archives up to September 30, 2004 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 Sponsor
          >>
          >> ADVERTISEMENT
          >>
          >>
          >> ________________________________
          >> Yahoo! Groups Links
          >>
          >> To visit your group on the web, go to:
          >> http://groups.yahoo.com/group/ocaml_beginners/
          >>
          >> To unsubscribe from this group, send an email to:
          >> ocaml_beginners-unsubscribe@yahoogroups.com
          >>
          >> Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
          >
          >
          > --
          > Seth Fogarty sfogarty@[gmail.com|rice.edu|livejournal]
          > Neep-neep at large AIM: Sorrath
          > "I know there are people in this world who do not love their fellow
          > human beings - and I hate people like that" --Tom Lehrer.
          >
          >
          >
          > Archives up to September 30, 2004 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
          >
          >
          >
          >
          >
          >
          >
          >


          --
          ` __ _ __ ___ ___| |_____ work web site: http://www.ctio.noao.edu/~andrew
          / _` / _/ _ \/ _ \ / / -_) personal web site: http://www.acooke.org/andrew
          \__,_\__\___/\___/_\_\___| list: http://www.acooke.org/andrew/compute.html
        • Seth J. Fogarty
          On Wed, 3 Nov 2004 21:54:11 -0300 (CLST), andrew cooke ... let example1 a b x = let a = f1 a in let b = f2 b in f3 a b x let example2 a b = let a = f1 a
          Message 4 of 26 , Nov 3, 2004
          • 0 Attachment
            On Wed, 3 Nov 2004 21:54:11 -0300 (CLST), andrew cooke
            <andrew@...> wrote:
            >
            > Thanks for the reply.
            >
            > Just to get this straight, because i think I wasn't anything like clear
            > enough (I was not talking about function signatures, but about when
            > evaluation occurs), are you saying that for the first two examples:
            >
            > let f = exampleN 1 2 in
            > ...
            > let g = f 3

            let example1 a b x =
            let a' = f1 a in
            let b' = f2 b in
            f3 a' b' x

            let example2 a b =
            let a' = f1 a in
            let b' = f2 b in
            fun x -> f3 a' b' x

            I am not certain of the exactly optimizations used for each of these.
            Technically, yes, the first repeats the work and the second doesn't. I
            would not be surprised the least if the OCaml compiler optimises them
            to the same thing. It has done worse voodoo before.

            > And for example3, where I was clearly way too brief (sorry), I was
            > assuming that the answer to the above was "yes" and then considering
            >
            > let f = fun (x -> example3 x 1 2) in
            > ...
            > let g = f 3
            >
            > Again, if g was evaluated in a loop, would that be as efficient as
            > examples 1 and 2?

            Baring acts of optimization, no, that would be the least efficient, as
            it has another closure, but it would preserve maximum polymorphism
            (i.e. if the type of x varied across the loop). Order-wise, same
            running time as example1.

            --
            Seth Fogarty sfogarty@[gmail.com|rice.edu|livejournal]
            Neep-neep at large AIM: Sorrath
            "I know there are people in this world who do not love their fellow
            human beings - and I hate people like that" --Tom Lehrer.
          • Martin Jambon
            ... You guys can play with the hidden counter example. The problem is: create a function that takes as argument the first value of a counter that should be
            Message 5 of 26 , Nov 3, 2004
            • 0 Attachment
              On Wed, 3 Nov 2004, Seth J. Fogarty wrote:

              >
              > On Wed, 3 Nov 2004 21:54:11 -0300 (CLST), andrew cooke
              > <andrew@...> wrote:
              > >
              > > Thanks for the reply.
              > >
              > > Just to get this straight, because i think I wasn't anything like clear
              > > enough (I was not talking about function signatures, but about when
              > > evaluation occurs), are you saying that for the first two examples:
              > >
              > > let f = exampleN 1 2 in
              > > ...
              > > let g = f 3
              >
              > let example1 a b x =
              > let a' = f1 a in
              > let b' = f2 b in
              > f3 a' b' x
              >
              > let example2 a b =
              > let a' = f1 a in
              > let b' = f2 b in
              > fun x -> f3 a' b' x
              >
              > I am not certain of the exactly optimizations used for each of these.
              > Technically, yes, the first repeats the work and the second doesn't. I
              > would not be surprised the least if the OCaml compiler optimises them
              > to the same thing. It has done worse voodoo before.

              You guys can play with the hidden counter example. The problem is:
              create a function that takes as argument the first value of a
              counter that should be created internally and returns two functions:
              - one that gives the current value of the counter
              - one that increments the counter

              This function should therefore have the following signature:

              val make_counter : int -> (unit -> int) * (unit -> unit)

              You should then be able to write something like:

              let (get, step) = make_counter 1


              Have fun!

              Martin
            • andrew cooke
              Thanks! (I hadn t even thought about how you might preserve polymorphism within the loop). Andrew ... -- ` __ _ __ ___ ___| |_____ work web site:
              Message 6 of 26 , Nov 4, 2004
              • 0 Attachment
                Thanks! (I hadn't even thought about how you might preserve polymorphism
                within the loop).

                Andrew

                Seth J. Fogarty said:
                >
                > On Wed, 3 Nov 2004 21:54:11 -0300 (CLST), andrew cooke
                > <andrew@...> wrote:
                >>
                >> Thanks for the reply.
                >>
                >> Just to get this straight, because i think I wasn't anything like clear
                >> enough (I was not talking about function signatures, but about when
                >> evaluation occurs), are you saying that for the first two examples:
                >>
                >> let f = exampleN 1 2 in
                >> ...
                >> let g = f 3
                >
                > let example1 a b x =
                > let a' = f1 a in
                > let b' = f2 b in
                > f3 a' b' x
                >
                > let example2 a b =
                > let a' = f1 a in
                > let b' = f2 b in
                > fun x -> f3 a' b' x
                >
                > I am not certain of the exactly optimizations used for each of these.
                > Technically, yes, the first repeats the work and the second doesn't. I
                > would not be surprised the least if the OCaml compiler optimises them
                > to the same thing. It has done worse voodoo before.
                >
                >> And for example3, where I was clearly way too brief (sorry), I was
                >> assuming that the answer to the above was "yes" and then considering
                >>
                >> let f = fun (x -> example3 x 1 2) in
                >> ...
                >> let g = f 3
                >>
                >> Again, if g was evaluated in a loop, would that be as efficient as
                >> examples 1 and 2?
                >
                > Baring acts of optimization, no, that would be the least efficient, as
                > it has another closure, but it would preserve maximum polymorphism
                > (i.e. if the type of x varied across the loop). Order-wise, same
                > running time as example1.
                >
                > --
                > Seth Fogarty sfogarty@[gmail.com|rice.edu|livejournal]
                > Neep-neep at large AIM: Sorrath
                > "I know there are people in this world who do not love their fellow
                > human beings - and I hate people like that" --Tom Lehrer.
                >
                >
                >
                > Archives up to September 30, 2004 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
                >
                >
                >
                >
                >
                >
                >
                >


                --
                ` __ _ __ ___ ___| |_____ work web site: http://www.ctio.noao.edu/~andrew
                / _` / _/ _ \/ _ \ / / -_) personal web site: http://www.acooke.org/andrew
                \__,_\__\___/\___/_\_\___| list: http://www.acooke.org/andrew/compute.html
              • andrew cooke
                That seems easy to do with a reference, but how does it shed light on the relative optimisations for examples 1 and 2? Are you saying that the optimisations
                Message 7 of 26 , Nov 4, 2004
                • 0 Attachment
                  That seems easy to do with a reference, but how does it shed light on the
                  relative optimisations for examples 1 and 2? Are you saying that the
                  optimisations used depend on whether there are mutable values (which I'm
                  sure is true)? Or that OCaml only does optimisations that are safe in the
                  presence of mutable values (which seems pretty limiting for a functional
                  language)?

                  Andrew

                  Martin Jambon said:
                  >
                  > On Wed, 3 Nov 2004, Seth J. Fogarty wrote:
                  >
                  >>
                  >> On Wed, 3 Nov 2004 21:54:11 -0300 (CLST), andrew cooke
                  >> <andrew@...> wrote:
                  >> >
                  >> > Thanks for the reply.
                  >> >
                  >> > Just to get this straight, because i think I wasn't anything like
                  >> clear
                  >> > enough (I was not talking about function signatures, but about when
                  >> > evaluation occurs), are you saying that for the first two examples:
                  >> >
                  >> > let f = exampleN 1 2 in
                  >> > ...
                  >> > let g = f 3
                  >>
                  >> let example1 a b x =
                  >> let a' = f1 a in
                  >> let b' = f2 b in
                  >> f3 a' b' x
                  >>
                  >> let example2 a b =
                  >> let a' = f1 a in
                  >> let b' = f2 b in
                  >> fun x -> f3 a' b' x
                  >>
                  >> I am not certain of the exactly optimizations used for each of these.
                  >> Technically, yes, the first repeats the work and the second doesn't. I
                  >> would not be surprised the least if the OCaml compiler optimises them
                  >> to the same thing. It has done worse voodoo before.
                  >
                  > You guys can play with the hidden counter example. The problem is:
                  > create a function that takes as argument the first value of a
                  > counter that should be created internally and returns two functions:
                  > - one that gives the current value of the counter
                  > - one that increments the counter
                  >
                  > This function should therefore have the following signature:
                  >
                  > val make_counter : int -> (unit -> int) * (unit -> unit)
                  >
                  > You should then be able to write something like:
                  >
                  > let (get, step) = make_counter 1
                  >
                  >
                  > Have fun!
                  >
                  > Martin
                  >
                  >
                  >
                  >
                  >
                  > Archives up to September 30, 2004 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
                  >
                  >
                  >
                  >
                  >
                  >
                  >
                  >


                  --
                  ` __ _ __ ___ ___| |_____ work web site: http://www.ctio.noao.edu/~andrew
                  / _` / _/ _ \/ _ \ / / -_) personal web site: http://www.acooke.org/andrew
                  \__,_\__\___/\___/_\_\___| list: http://www.acooke.org/andrew/compute.html
                • Martin Jambon
                  ... Yes. OCaml is not a pure functional language. It is possible to make a program compute things in a specified order without difficulties. And the compiler
                  Message 8 of 26 , Nov 4, 2004
                  • 0 Attachment
                    On Thu, 4 Nov 2004, andrew cooke wrote:

                    > That seems easy to do with a reference, but how does it shed light on the
                    > relative optimisations for examples 1 and 2? Are you saying that the
                    > optimisations used depend on whether there are mutable values (which I'm
                    > sure is true)?
                    > Or that OCaml only does optimisations that are safe in the
                    > presence of mutable values (which seems pretty limiting for a functional
                    > language)?

                    Yes. OCaml is not a pure functional language. It is possible to make a
                    program compute things in a specified order without difficulties.
                    And the compiler generally doesn't know which functions perform side
                    effects.
                    You can write:
                    for i = 1 to 100_000_000 do
                    ignore (1 + 1)
                    done

                    This will perform 100 million times the same addition.

                    These examples have a different semantics:

                    >> let example1 a b x =
                    >> let a' = f1 a in
                    >> let b' = f2 b in
                    >> f3 a' b' x

                    example1 a b just creates an object that is a function that will accept
                    one argument (x) and compute everything after the equal
                    sign (=)

                    example1 a b x computes everything after the equal sign

                    >> let example2 a b =
                    >> let a' = f1 a in
                    >> let b' = f2 b in
                    >> fun x -> f3 a' b' x

                    example2 a b computes everything after the equal sign:
                    - f1 a
                    - f2 b
                    - builds the function which is returned as a result

                    example2 a b x is strictly equivalent to
                    (example2 a b) x which computes the following:
                    - f1 a
                    - f2 b
                    - applies (fun x -> f3 a' b') to x which may not
                    involve the creation of a specific object
                    representing the temporary function because it is
                    applied immediately (that's a possible optimisation)

                    Note that example1 can be rewritten as:

                    let example1' a b =
                    fun x ->
                    let a' = f1 a in
                    let b' = f2 b in
                    f3 a' b' x

                    example1' a b like before, computes everything after the equal sign,
                    which only consists in building a function that may even
                    not exist as a physical object (e.g. if it is applied
                    immediately).

                    The following is the example of the counter. It is essential to be sure
                    when a new counter is created and when not:

                    [droopy] ~ % ledit ocaml
                    Objective Caml version 3.08.1

                    # let make_counter init =
                    let counter = ref init in
                    ((fun () -> !counter), (fun () -> incr counter));;
                    val make_counter : int -> (unit -> int) * (unit -> unit) = <fun>
                    # let (get1, step1) = make_counter 1;;
                    val get1 : unit -> int = <fun>
                    val step1 : unit -> unit = <fun>
                    # let (get2, step2) = make_counter 1;;
                    val get2 : unit -> int = <fun>
                    val step2 : unit -> unit = <fun>
                    # get1 ();;
                    - : int = 1
                    # get2 ();;
                    - : int = 1
                    # step1 ();;
                    - : unit = ()
                    # get1 ();;
                    - : int = 2
                    # get2 ();;
                    - : int = 1


                    In practice, this kind of things can be useful if a datastructure has to
                    be initialized, e.g.:

                    let is_in l =
                    let tbl = Hashtbl.create (List.length l) in
                    List.iter (fun aa -> Hashtbl.add tbl aa ()) l;
                    Hashtbl.mem tbl

                    let is_in_abc = is_in ['a'; 'b'; 'c']
                    let is_in_123 = is_in [1; 2; 3; 12; 23; 31; 123; 231; 312]


                    Martin
                  • Seth J. Fogarty
                    RE: counter example. That was easy enough. Still not sure why # let f1 x = x;; val f1 : a - a = # let f2 x = x;; val f2 : a - a = # let f3 a
                    Message 9 of 26 , Nov 4, 2004
                    • 0 Attachment
                      RE: counter example.
                      That was easy enough. Still not sure why

                      # let f1 x = x;;
                      val f1 : 'a -> 'a = <fun>
                      # let f2 x = x;;
                      val f2 : 'a -> 'a = <fun>
                      # let f3 a b c = (a,b,c);;
                      val f3 : 'a -> 'b -> 'c -> 'a * 'b * 'c = <fun>
                      # let example2 a b =
                      let a' = f1 a
                      and b' = f2 b
                      in (fun x -> f3 a' b' x);;
                      val example2 : 'a -> 'b -> 'c -> 'a * 'b * 'c = <fun>
                      # let f = example2 1 2;;
                      val f : '_a -> int * int * '_a = <fun>

                      results in f not being fully polymorphic, but
                      val example1 : 'a -> 'b -> 'c -> 'a * 'b * 'c = <fun>
                      let f = fun x -> example1 1 2 x;;
                      val f : 'a -> int * int * 'a = <fun>

                      Does. It seems to me that I should be able to return a (fun x- >
                      blah), and have it be as polymorphic as possible. (not should in the
                      'right thing' sense, but should in the 'actual way it works' sense,
                      based on my very poor knowledge of ocaml types and '_a).

                      --
                      Seth Fogarty sfogarty@[gmail.com|rice.edu|livejournal]
                      Neep-neep at large AIM: Sorrath
                      "I know there are people in this world who do not love their fellow
                      human beings - and I hate people like that" --Tom Lehrer.
                    • Martin Jambon
                      ... I don t know why it is like this (but I don t want to know :-) There are a few paragraphs about this topic in the FAQ if you did not read it yet:
                      Message 10 of 26 , Nov 4, 2004
                      • 0 Attachment
                        On Thu, 4 Nov 2004, Seth J. Fogarty wrote:

                        > RE: counter example.
                        > That was easy enough. Still not sure why
                        >
                        > # let f1 x = x;;
                        > val f1 : 'a -> 'a = <fun>
                        > # let f2 x = x;;
                        > val f2 : 'a -> 'a = <fun>
                        > # let f3 a b c = (a,b,c);;
                        > val f3 : 'a -> 'b -> 'c -> 'a * 'b * 'c = <fun>
                        > # let example2 a b =
                        > let a' = f1 a
                        > and b' = f2 b
                        > in (fun x -> f3 a' b' x);;
                        > val example2 : 'a -> 'b -> 'c -> 'a * 'b * 'c = <fun>
                        > # let f = example2 1 2;;
                        > val f : '_a -> int * int * '_a = <fun>
                        >
                        > results in f not being fully polymorphic, but
                        > val example1 : 'a -> 'b -> 'c -> 'a * 'b * 'c = <fun>
                        > let f = fun x -> example1 1 2 x;;
                        > val f : 'a -> int * int * 'a = <fun>
                        >
                        > Does. It seems to me that I should be able to return a (fun x- >
                        > blah), and have it be as polymorphic as possible. (not should in the
                        > 'right thing' sense, but should in the 'actual way it works' sense,
                        > based on my very poor knowledge of ocaml types and '_a).

                        I don't know why it is like this (but I don't want to know :-)
                        There are a few paragraphs about this topic in the FAQ if you did not read
                        it yet:
                        http://caml.inria.fr/FAQ/FAQ_EXPERT-eng.html#variables_de_types_faibles


                        Martin
                      • Nicolas Cannasse
                        ... The monomorphic types _a and others are needed in order to ensure type safety. for example : let id x = x let f = ref id ... if it s type was a - a ,
                        Message 11 of 26 , Nov 4, 2004
                        • 0 Attachment
                          > results in f not being fully polymorphic, but
                          > val example1 : 'a -> 'b -> 'c -> 'a * 'b * 'c = <fun>
                          > let f = fun x -> example1 1 2 x;;
                          > val f : 'a -> int * int * 'a = <fun>
                          >
                          > Does. It seems to me that I should be able to return a (fun x- >
                          > blah), and have it be as polymorphic as possible. (not should in the
                          > 'right thing' sense, but should in the 'actual way it works' sense,
                          > based on my very poor knowledge of ocaml types and '_a).

                          The monomorphic types '_a and others are needed in order to ensure type
                          safety.
                          for example :

                          let id x = x
                          let f = ref id

                          > f will be '_a -> '_a ref
                          if it's type was 'a -> 'a , that means we can put any unifiable function
                          into the reference f and call it later with another type :

                          f := (fun x -> x + 1) // would unify since int -> int is unifiable with
                          'a -> 'a
                          !f "hello" // would works since !f would still be 'a -> 'a, causing a typing
                          error since we're actually executing above function

                          So it's needed to introduce monomorphic variables, they are really
                          "temporary" polymorphic variables until they're unified. And this limitation
                          is only required for values " let x = " since polymorphic functions does
                          not cause any problem.

                          Nicolas Cannasse
                        • Seth J. Fogarty
                          I had seen those, yes. Still don t really undersand it. Are the pages translated? On Thu, 4 Nov 2004 18:28:21 -0800 (PST), Martin Jambon ... -- Seth Fogarty
                          Message 12 of 26 , Nov 4, 2004
                          • 0 Attachment
                            I had seen those, yes. Still don't really undersand it. Are the pages
                            translated?


                            On Thu, 4 Nov 2004 18:28:21 -0800 (PST), Martin Jambon
                            <martin_jambon@...> wrote:
                            > On Thu, 4 Nov 2004, Seth J. Fogarty wrote:
                            >
                            >
                            >
                            > > RE: counter example.
                            > > That was easy enough. Still not sure why
                            > >
                            > > # let f1 x = x;;
                            > > val f1 : 'a -> 'a = <fun>
                            > > # let f2 x = x;;
                            > > val f2 : 'a -> 'a = <fun>
                            > > # let f3 a b c = (a,b,c);;
                            > > val f3 : 'a -> 'b -> 'c -> 'a * 'b * 'c = <fun>
                            > > # let example2 a b =
                            > > let a' = f1 a
                            > > and b' = f2 b
                            > > in (fun x -> f3 a' b' x);;
                            > > val example2 : 'a -> 'b -> 'c -> 'a * 'b * 'c = <fun>
                            > > # let f = example2 1 2;;
                            > > val f : '_a -> int * int * '_a = <fun>
                            > >
                            > > results in f not being fully polymorphic, but
                            > > val example1 : 'a -> 'b -> 'c -> 'a * 'b * 'c = <fun>
                            > > let f = fun x -> example1 1 2 x;;
                            > > val f : 'a -> int * int * 'a = <fun>
                            > >
                            > > Does. It seems to me that I should be able to return a (fun x- >
                            > > blah), and have it be as polymorphic as possible. (not should in the
                            > > 'right thing' sense, but should in the 'actual way it works' sense,
                            > > based on my very poor knowledge of ocaml types and '_a).
                            >
                            > I don't know why it is like this (but I don't want to know :-)
                            > There are a few paragraphs about this topic in the FAQ if you did not read
                            > it yet:
                            > http://caml.inria.fr/FAQ/FAQ_EXPERT-eng.html#variables_de_types_faibles
                            >
                            >
                            > Martin
                            >
                            >
                            >
                            >
                            >
                            >
                            > Archives up to September 30, 2004 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 Sponsor
                            >
                            > ADVERTISEMENT
                            >
                            >
                            > ________________________________
                            > Yahoo! Groups Links
                            >
                            > To visit your group on the web, go to:
                            > http://groups.yahoo.com/group/ocaml_beginners/
                            >
                            > To unsubscribe from this group, send an email to:
                            > ocaml_beginners-unsubscribe@yahoogroups.com
                            >
                            > Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.


                            --
                            Seth Fogarty sfogarty@[gmail.com|rice.edu|livejournal]
                            Neep-neep at large AIM: Sorrath
                            "I know there are people in this world who do not love their fellow
                            human beings - and I hate people like that" --Tom Lehrer.
                          • Seth J. Fogarty
                            ... Thanks... that s the example I needed to fit this in my head. I m still slightly bothered by the fragility with which _a is introduced or not. # let f a b
                            Message 13 of 26 , Nov 5, 2004
                            • 0 Attachment
                              On Fri, 5 Nov 2004 11:49:41 +0900, Nicolas Cannasse <warplayer@...> wrote:
                              >
                              >
                              > > results in f not being fully polymorphic, but
                              > > val example1 : 'a -> 'b -> 'c -> 'a * 'b * 'c = <fun>
                              > > let f = fun x -> example1 1 2 x;;
                              > > val f : 'a -> int * int * 'a = <fun>
                              > >
                              > > Does. It seems to me that I should be able to return a (fun x- >
                              > > blah), and have it be as polymorphic as possible. (not should in the
                              > > 'right thing' sense, but should in the 'actual way it works' sense,
                              > > based on my very poor knowledge of ocaml types and '_a).
                              >
                              > The monomorphic types '_a and others are needed in order to ensure type
                              > safety.
                              > for example :
                              >
                              > let id x = x
                              > let f = ref id

                              Thanks... that's the example I needed to fit this in my head.

                              I'm still slightly bothered by the fragility with which '_a is
                              introduced or not.
                              # let f a b = (a,b);;
                              val f : 'a -> 'b -> 'a * 'b = <fun>
                              # let g = f 1;;
                              val g : '_a -> int * '_a = <fun>
                              # let g = fun x -> f 1 x;;
                              val g : 'a -> int * 'a = <fun>
                              # let g = ignore 5; fun x -> f 1 x;;
                              val g : '_a -> int * '_a = <fun>
                              # let g = if true then fun x -> f 1 x else fun x -> f 1 x;;
                              val g : 'a -> int * 'a = <fun>

                              I cannot figure out when I will get a '_a and when I will not.
                              --
                              Seth Fogarty sfogarty@[gmail.com|rice.edu|livejournal]
                              Neep-neep at large AIM: Sorrath
                              "I know there are people in this world who do not love their fellow
                              human beings - and I hate people like that" --Tom Lehrer.
                            • Nicolas Cannasse
                              ... It s easy. You get monorphic variables every time you having polymorphic variables on the right side of a let x = ... expression . That means for values
                              Message 14 of 26 , Nov 5, 2004
                              • 0 Attachment
                                > Thanks... that's the example I needed to fit this in my head.
                                >
                                > I'm still slightly bothered by the fragility with which '_a is
                                > introduced or not.

                                It's easy.
                                You get monorphic variables every time you having polymorphic variables on
                                the right side of a let x = ... expression . That means for values and not
                                for functions. And in some cases the compiler can relieve the monorphics and
                                turn them polymorphics, in some hard coded special cases known to be
                                secure - such as simple assignations - at least I think.

                                Nicolas Cannasse
                              • Remi Vanicat
                                On Wed, 3 Nov 2004 16:03:20 -0300 (CLST), andrew cooke ... The awnser of Issac is correct, but I wabt to insist one one thing : the ocaml semantic is the more
                                Message 15 of 26 , Nov 5, 2004
                                • 0 Attachment
                                  On Wed, 3 Nov 2004 16:03:20 -0300 (CLST), andrew cooke
                                  <andrew@...> wrote:
                                  >
                                  >
                                  > Where can I find a clear description of how OCaml executes code. In
                                  > particular, I want to understand when functions with several values are
                                  > evaluated - is the evaluation progressive (during Currying) or is
                                  > evaluation delayed until all arguments are present.
                                  >
                                  > For example, are the following equivalent, always?
                                  >
                                  > let example1 a b x =
                                  > let a' = f1 a in
                                  > let b' = f2 b in
                                  > f3 a' b' x
                                  >
                                  > let example2 a b =
                                  > let a' = f1 a in
                                  > let b' = f2 b in
                                  > fun x -> f3 a' b' x

                                  The awnser of Issac is correct, but I wabt to insist one one thing :
                                  the ocaml semantic is the more natural one. In the first exemple, you
                                  have define a function that wait for three argument before making any
                                  computation, in the second exemple, you've define a function that wait
                                  for two argument, then do part of the computation then do another
                                  computation. What will happen is what you read.
                                • Remi Vanicat
                                  ... well, when the typer compute the type of an expression, he only know the type of the part of the computation. So if two function do have the same type, and
                                  Message 16 of 26 , Nov 5, 2004
                                  • 0 Attachment
                                    On Wed, 3 Nov 2004 16:28:00 -0600, Seth J. Fogarty <sfogarty@...> wrote:
                                    >
                                    > On Wed, 3 Nov 2004 16:03:20 -0300 (CLST), andrew cooke
                                    >
                                    >
                                    > <andrew@...> wrote:
                                    > >
                                    > > Where can I find a clear description of how OCaml executes code. In
                                    > > particular, I want to understand when functions with several values are
                                    > > evaluated - is the evaluation progressive (during Currying) or is
                                    > > evaluation delayed until all arguments are present.
                                    > >
                                    > > For example, are the following equivalent, always?
                                    > >
                                    > > let example1 a b x =
                                    > > let a' = f1 a in
                                    > > let b' = f2 b in
                                    > > f3 a' b' x
                                    > >
                                    > > let example2 a b =
                                    > > let a' = f1 a in
                                    > > let b' = f2 b in
                                    > > fun x -> f3 a' b' x
                                    >
                                    > These two are equivalent. I have a question, however, for the list.
                                    > Why does example2, when so explicitly curried as such, have a '_a when
                                    > curried?
                                    >
                                    > # let a = example2 1 2;;
                                    > val a : '_a -> int * int * '_a = <fun>

                                    well, when the typer compute the type of an expression, he only know
                                    the type of the part of the computation. So if two function do have
                                    the same type, and you apply it to sthe same argument, you have the
                                    same type as a result.
                                  • Alwyn
                                    ... It s called value restriction . For full polymorphism, the expression on the right hand side of the = sign must be a value. ... (a,b) is a value. ... f
                                    Message 17 of 26 , Nov 5, 2004
                                    • 0 Attachment
                                      On 5 Nov 2004, at 08:57, Seth J. Fogarty wrote:

                                      > I'm still slightly bothered by the fragility with which '_a is
                                      > introduced or not.

                                      It's called 'value restriction'. For full polymorphism, the expression
                                      on the right hand side of the '=' sign must be a value.

                                      > # let f a b = (a,b);;
                                      > val f : 'a -> 'b -> 'a * 'b = <fun>

                                      (a,b) is a value.

                                      > # let g = f 1;;
                                      > val g : '_a -> int * '_a = <fun>

                                      'f 1' is a partial function application. Not a value. Can be resolved
                                      by eta-expansion to:
                                      let g x = f 1 x;;

                                      or as below:

                                      > # let g = fun x -> f 1 x;;
                                      > val g : 'a -> int * 'a = <fun>

                                      Lambda expression. This is a value.

                                      > # let g = ignore 5; fun x -> f 1 x;;
                                      > val g : '_a -> int * '_a = <fun>

                                      Sequence of expressions, the first potentially side-effecting. Not a
                                      value.

                                      > # let g = if true then fun x -> f 1 x else fun x -> f 1 x;;
                                      > val g : 'a -> int * 'a = <fun>

                                      Evaluates to a lambda expression.

                                      As has been explained earlier, this restriction on polymorphism has
                                      been made because ML, being an imperative language, allows assignment
                                      to mutable variables, potentially compromising the type system. The
                                      result is somewhat unfortunate, in that polymorphism is denied in many
                                      cases (like the above) where it would be entirely type-safe. In
                                      practice, though, it turns out not to be a problem and can in many
                                      cases be avoided by eta-expansion.

                                      HTH

                                      Alwyn
                                    • Richard Jones
                                      ... And I think it s also true that _a will only ever appear in the toplevel, never when writing proper applications. Rich. -- Richard Jones.
                                      Message 18 of 26 , Nov 5, 2004
                                      • 0 Attachment
                                        On Fri, Nov 05, 2004 at 11:49:41AM +0900, Nicolas Cannasse wrote:
                                        > > f will be '_a -> '_a ref
                                        > if it's type was 'a -> 'a , that means we can put any unifiable function
                                        > into the reference f and call it later with another type :
                                        >
                                        > f := (fun x -> x + 1) // would unify since int -> int is unifiable with
                                        > 'a -> 'a
                                        > !f "hello" // would works since !f would still be 'a -> 'a, causing a typing
                                        > error since we're actually executing above function
                                        >
                                        > So it's needed to introduce monomorphic variables, they are really
                                        > "temporary" polymorphic variables until they're unified.

                                        And I think it's also true that '_a will only ever appear in the
                                        toplevel, never when writing proper applications.

                                        Rich.

                                        --
                                        Richard Jones. http://www.annexia.org/ http://www.j-london.com/
                                        >>> http://www.team-notepad.com/ - collaboration tools for teams <<<
                                        Merjis Ltd. http://www.merjis.com/ - improving website return on investment
                                        Use Perl libs in OCaml - http://www.merjis.com/developers/perl4caml


                                        [Non-text portions of this message have been removed]
                                      • Remi Vanicat
                                        ... Well not exactly, if the value on the right hand side of the = is an hashtable for example, it is a value, but it won t be polymophic (it would be realy
                                        Message 19 of 26 , Nov 5, 2004
                                        • 0 Attachment
                                          On Fri, 5 Nov 2004 12:59:29 +0000, Alwyn <dt015a1979@...> wrote:
                                          >
                                          > On 5 Nov 2004, at 08:57, Seth J. Fogarty wrote:
                                          >
                                          > > I'm still slightly bothered by the fragility with which '_a is
                                          > > introduced or not.
                                          >
                                          > It's called 'value restriction'. For full polymorphism, the expression
                                          > on the right hand side of the '=' sign must be a value.
                                          >

                                          Well not exactly, if the value on the right hand side of the = is an
                                          hashtable for example, it is a value, but it won't be polymophic (it
                                          would be realy unsafe). Only imutable value will be generalize (that
                                          is render fully polymorphic). Well, not exactly this, it will be
                                          generalize if the type polymorphisme is covariant (and I believe there
                                          is another restriction).

                                          A type 'a t is covariant with regard to a, if for any type a and b
                                          such that one can coerce any value of type a in a value of type b,
                                          then one can coerce a value of type a t into a value of type b t. For
                                          example the option type is covariant.
                                        • Remi Vanicat
                                          ... Not exatly, the fact is that if there is an _a type in a proper application, this is an error, and the compiler will refuse to compile it.
                                          Message 20 of 26 , Nov 5, 2004
                                          • 0 Attachment
                                            On Fri, 5 Nov 2004 13:10:40 +0000, Richard Jones <rich@...> wrote:
                                            >
                                            >
                                            >
                                            > On Fri, Nov 05, 2004 at 11:49:41AM +0900, Nicolas Cannasse wrote:
                                            > > > f will be '_a -> '_a ref
                                            > > if it's type was 'a -> 'a , that means we can put any unifiable function
                                            > > into the reference f and call it later with another type :
                                            > >
                                            > > f := (fun x -> x + 1) // would unify since int -> int is unifiable with
                                            > > 'a -> 'a
                                            > > !f "hello" // would works since !f would still be 'a -> 'a, causing a typing
                                            > > error since we're actually executing above function
                                            > >
                                            > > So it's needed to introduce monomorphic variables, they are really
                                            > > "temporary" polymorphic variables until they're unified.
                                            >
                                            > And I think it's also true that '_a will only ever appear in the
                                            > toplevel, never when writing proper applications.
                                            >

                                            Not exatly, the fact is that if there is an '_a type in a proper
                                            application, this is an error, and the compiler will refuse to compile
                                            it.
                                          • Alwyn
                                            ... I was under the impression that current O Caml, like SML 97, employed a system of value polymorphism as suggested by Andrew Wright in his paper Simple
                                            Message 21 of 26 , Nov 5, 2004
                                            • 0 Attachment
                                              On 5 Nov 2004, at 13:19, Remi Vanicat wrote:

                                              > On Fri, 5 Nov 2004 12:59:29 +0000, Alwyn <dt015a1979@...>
                                              > wrote:
                                              > >
                                              > > It's called 'value restriction'. For full polymorphism, the
                                              > expression
                                              > > on the right hand side of the '=' sign must be a value.
                                              >
                                              > Well not exactly, if the value on the right hand side of the = is an
                                              > hashtable for example, it is a value, but it won't be polymophic (it
                                              > would be realy unsafe).

                                              I was under the impression that current O'Caml, like SML 97, employed a
                                              system of value polymorphism as suggested by Andrew Wright in his paper
                                              "Simple Imperative Polymorphism" published in 1995. See:
                                              <http://www.smlnj.org//doc/Conversion/types.html>

                                              <quote>
                                              As in SML '90, we approximate the class of safe-to-generalize
                                              expressions conservatively by the simple syntactic notion of a
                                              nonexpansive expression, also known as a value expression or simply a
                                              value. SML '90 defined nonexpansive expressions to include the
                                              following atomic forms:
                                              • constants (e.g. 3),
                                              • nullary constructors (e.g. nil),
                                              • variables (e.g. x, A.x),
                                              • function expressions (e.g. (fn x => x)).
                                              It is clear that the evaluation of any of these forms is safe because
                                              it cannot entail the creation of new data structures (other than the
                                              benign case of creating function closures for function expressions). To
                                              partially compensate for the fact that we are being more restrictive in
                                              our creation of polymorphism, SML '97 enlarges the class of
                                              nonexpansive expressions to include some simple compound expressions:
                                              • records and tuples with nonexpansive fields (e.g. (3,x,nil)),
                                              • constructors (except ref) applied to nonexpansive arguments (e.g.
                                              x::nil).
                                              All other expressions, including function applications, let
                                              expressions, conditionals, etc., are by definition expansive, implying
                                              that their evaluation may entail nontrivial computations that might
                                              lead to the creation of ref cells or other mutable data structures.
                                              </quote>

                                              > Only imutable value will be generalize (that
                                              > is render fully polymorphic). Well, not exactly this, it will be
                                              > generalize if the type polymorphisme is covariant (and I believe there
                                              > is another restriction).

                                              I haven't been able to find an authoritative source on this subject
                                              with regard to O'Caml either in English or in French. Do you know of
                                              any?


                                              Alwyn
                                            • Seth J. Fogarty
                                              Yup. Alright, I will buy that. Still not sure why ; is treated fundementally different than if..then..else. ... -- Seth Fogarty
                                              Message 22 of 26 , Nov 5, 2004
                                              • 0 Attachment
                                                Yup. Alright, I will buy that. Still not sure why ; is treated
                                                fundementally different than if..then..else.


                                                On Fri, 5 Nov 2004 13:52:20 +0100, Remi Vanicat <remi.vanicat@...> wrote:
                                                > On Wed, 3 Nov 2004 16:28:00 -0600, Seth J. Fogarty <sfogarty@...>
                                                > wrote:
                                                >
                                                >
                                                > >
                                                > > On Wed, 3 Nov 2004 16:03:20 -0300 (CLST), andrew cooke
                                                > >
                                                > >
                                                > > <andrew@...> wrote:
                                                > > >
                                                > > > Where can I find a clear description of how OCaml executes code. In
                                                > > > particular, I want to understand when functions with several values
                                                > are
                                                > > > evaluated - is the evaluation progressive (during Currying) or is
                                                > > > evaluation delayed until all arguments are present.
                                                > > >
                                                > > > For example, are the following equivalent, always?
                                                > > >
                                                > > > let example1 a b x =
                                                > > > let a' = f1 a in
                                                > > > let b' = f2 b in
                                                > > > f3 a' b' x
                                                > > >
                                                > > > let example2 a b =
                                                > > > let a' = f1 a in
                                                > > > let b' = f2 b in
                                                > > > fun x -> f3 a' b' x
                                                > >
                                                > > These two are equivalent. I have a question, however, for the list.
                                                > > Why does example2, when so explicitly curried as such, have a '_a when
                                                > > curried?
                                                > >
                                                > > # let a = example2 1 2;;
                                                > > val a : '_a -> int * int * '_a = <fun>
                                                >
                                                > well, when the typer compute the type of an expression, he only know
                                                > the type of the part of the computation. So if two function do have
                                                > the same type, and you apply it to sthe same argument, you have the
                                                > same type as a result.
                                                >
                                                >
                                                >
                                                >
                                                > Archives up to September 30, 2004 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 Sponsor
                                                >
                                                > ADVERTISEMENT
                                                >
                                                >
                                                > ________________________________
                                                > Yahoo! Groups Links
                                                >
                                                > To visit your group on the web, go to:
                                                > http://groups.yahoo.com/group/ocaml_beginners/
                                                >
                                                > To unsubscribe from this group, send an email to:
                                                > ocaml_beginners-unsubscribe@yahoogroups.com
                                                >
                                                > Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.


                                                --
                                                Seth Fogarty sfogarty@[gmail.com|rice.edu|livejournal]
                                                Neep-neep at large AIM: Sorrath
                                                "I know there are people in this world who do not love their fellow
                                                human beings - and I hate people like that" --Tom Lehrer.
                                              • Remi Vanicat
                                                ... well, I belive that there is this, and some other value, but I ve difficulties to explain when exacltly. ... there is a bug report about it in the ocaml
                                                Message 23 of 26 , Nov 9, 2004
                                                • 0 Attachment
                                                  On Fri, 5 Nov 2004 17:46:54 +0000, Alwyn <dt015a1979@...> wrote:
                                                  >
                                                  >
                                                  >
                                                  > On 5 Nov 2004, at 13:19, Remi Vanicat wrote:
                                                  >
                                                  > > On Fri, 5 Nov 2004 12:59:29 +0000, Alwyn <dt015a1979@...>
                                                  > > wrote:
                                                  > > >
                                                  > > > It's called 'value restriction'. For full polymorphism, the
                                                  > > expression
                                                  > > > on the right hand side of the '=' sign must be a value.
                                                  > >
                                                  > > Well not exactly, if the value on the right hand side of the = is an
                                                  > > hashtable for example, it is a value, but it won't be polymophic (it
                                                  > > would be realy unsafe).
                                                  >
                                                  > I was under the impression that current O'Caml, like SML 97, employed a
                                                  > system of value polymorphism as suggested by Andrew Wright in his paper
                                                  > "Simple Imperative Polymorphism" published in 1995. See:
                                                  > <http://www.smlnj.org//doc/Conversion/types.html>
                                                  >
                                                  > <quote>
                                                  > As in SML '90, we approximate the class of safe-to-generalize
                                                  > expressions conservatively by the simple syntactic notion of a
                                                  > nonexpansive expression, also known as a value expression or simply a
                                                  > value. SML '90 defined nonexpansive expressions to include the
                                                  > following atomic forms:
                                                  > • constants (e.g. 3),
                                                  > • nullary constructors (e.g. nil),
                                                  > • variables (e.g. x, A.x),
                                                  > • function expressions (e.g. (fn x => x)).
                                                  > It is clear that the evaluation of any of these forms is safe because
                                                  > it cannot entail the creation of new data structures (other than the
                                                  > benign case of creating function closures for function expressions). To
                                                  > partially compensate for the fact that we are being more restrictive in
                                                  > our creation of polymorphism, SML '97 enlarges the class of
                                                  > nonexpansive expressions to include some simple compound expressions:
                                                  > • records and tuples with nonexpansive fields (e.g. (3,x,nil)),
                                                  > • constructors (except ref) applied to nonexpansive arguments (e.g.
                                                  > x::nil).
                                                  > All other expressions, including function applications, let
                                                  > expressions, conditionals, etc., are by definition expansive, implying
                                                  > that their evaluation may entail nontrivial computations that might
                                                  > lead to the creation of ref cells or other mutable data structures.
                                                  > </quote>

                                                  well, I belive that there is this, and some other value, but I've
                                                  difficulties to explain when exacltly.

                                                  >
                                                  > > Only imutable value will be generalize (that
                                                  > > is render fully polymorphic). Well, not exactly this, it will be
                                                  > > generalize if the type polymorphisme is covariant (and I believe there
                                                  > > is another restriction).
                                                  >
                                                  > I haven't been able to find an authoritative source on this subject
                                                  > with regard to O'Caml either in English or in French. Do you know of
                                                  > any?

                                                  there is a bug report about it in the ocaml bug tracking
                                                  http://caml.inria.fr/bin/caml-bugs/fixed?id=1692;expression=vanicat;page=2;user=guest
                                                  you could also try to find messages on the mailing list speaking about it
                                                • Alwyn
                                                  ... Thank you; this led me to Garrigue s publications page at: I have another question: In Standard ML
                                                  Message 24 of 26 , Nov 9, 2004
                                                  • 0 Attachment
                                                    On 9 Nov 2004, at 12:23, Remi Vanicat wrote:

                                                    > there is a bug report about it in the ocaml bug tracking
                                                    > http://caml.inria.fr/bin/caml-bugs/fixed?id=1692;expression=vanicat;
                                                    > page=2;user=guest

                                                    Thank you; this led me to Garrigue's publications page at:
                                                    <http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/papers/>

                                                    I have another question: In Standard ML and Haskell, constructors can
                                                    be used as functions. Why is this not the case in CAML?


                                                    Alwyn
                                                  • Remi Vanicat
                                                    ... Well, in the 3 said language, construcor are mainly tag that are put in the header of the object, and type declaration for type safety. Then one can decide
                                                    Message 25 of 26 , Nov 11, 2004
                                                    • 0 Attachment
                                                      On Tue, 9 Nov 2004 19:57:38 +0000, Alwyn <dt015a1979@...> wrote:

                                                      > I have another question: In Standard ML and Haskell, constructors can
                                                      > be used as functions. Why is this not the case in CAML?

                                                      Well, in the 3 said language, construcor are mainly tag that are put
                                                      in the header of the object, and type declaration for type safety.
                                                      Then one can decide to define a function to build such a value. But it
                                                      is not automatic. So ocaml choose to not do it, while the two other
                                                      said language do. It is a design decision, there is no real good
                                                      reason against it (At least in my knowledge)
                                                    Your message has been successfully submitted and would be delivered to recipients shortly.