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

Re: "ocaml_beginners"::[] Copying lists, changing it's elements and being astouned how imperative it is!

Expand Messages
  • Remi Vanicat
    ... Hello, ... Because there is only one list, as a # l1 == l2;; would have prove you. O Caml share everything, unless you expressively make it otherwise. If
    Message 1 of 9 , Feb 28, 2003
    • 0 Attachment
      oliver@...-berlin.de writes:

      > Hello,

      Hello,

      >
      >
      > that seems to be absolutely a beginners question,
      > so I'm back to the Ocamlbeginners-mailinglist.
      >
      > Well, here is what I've done:
      >
      > =====================================================
      > oliver@sam:~ > ocaml
      > Objective Caml version 3.04
      >
      > # let l1 = [ "aaa"; "bbb"; "ccc"];;
      > val l1 : string list = ["aaa"; "bbb"; "ccc"]
      > # let l2 = l1;;
      > val l2 : string list = ["aaa"; "bbb"; "ccc"]
      > # (List.hd l2).[2] <- 'Z';;
      > - : unit = ()
      > # l1;;
      > - : string list = ["aaZ"; "bbb"; "ccc"]
      > # l2;;
      > - : string list = ["aaZ"; "bbb"; "ccc"]
      > #
      > =====================================================
      >
      > Why are _both_ lists changed?

      Because there is only one list, as a

      # l1 == l2;;

      would have prove you.

      O'Caml share everything, unless you expressively make it otherwise.

      If you want l2 to be a copy of l1, you would have to do it like this:

      # let rec copy = function
      | [] -> []
      | x::rest -> x::(copy rest);;
      val copy : 'a list -> 'a list = <fun>
      # let l2 = copy l1;;
      val l2 : string list = ["aaa"; "bbb"; "ccc"]
      # l1 == l2;;
      - : bool = false

      but then, if l2 is a copy of l1, the two list share the strings, so :

      # (List.hd l2).[2] <- 'Z';;
      - : unit = ()
      # l1;;
      - : string list = ["aaZ"; "bbb"; "ccc"]
      # l2;;
      - : string list = ["aaZ"; "bbb"; "ccc"]

      So you have to copy the strings inside the list :
      # let l2 = List.map String.copy l1;;
      val l2 : string list = ["aaZ"; "bbb"; "ccc"]
      # (List.hd l2).[2] <- 'A';;
      - : unit = ()
      # l2;;
      - : string list = ["aaA"; "bbb"; "ccc"]
      # l1;;
      - : string list = ["aaZ"; "bbb"; "ccc"]

      > And much more pain and panic creates the next question:
      >
      > Why is it possible to change the list's contents?
      > Shouldn't (List.hd l2) give back a result, which
      > (only the result) is then afterwards changed?
      > (That's, what I think would be functional programming!)

      No. functional programming would be to forbid any change. But O'Caml is
      not purely functional, and an example of non functional part are
      string, and in particular string manipulation.

      >
      > Why is this result directly connected to the
      > list itself, and is not a derived value?
      >
      > Where is functional programming's advantage here?

      You're using imperative things here, not functional one...

      >
      >
      > If I would use Arrays here (instead of Lists) then I would
      > be irritated, but not be shocked.
      > Now, where I use lists and can change

      The list haven't been changed. They contain exactly the same strings
      (the same block of memory). But this strings have changed.

      > them in an imperative way, I'm absolutely confused and shocked and
      > irritated!
      >
      > So, I can create side effects by changing the data in this way?!

      changing data are side effect.

      When you are doing something like
      (List.hd l2).[2] <- 'Z';;

      This doesn't have any useful returned value. The result of this line
      is the modification of a string. This is a side effect.

      If you want a side effect free language, try Haskell or Clean.

      [...]


      --
      Rémi Vanicat
      vanicat@labri.u-bordeaux.fr
      http://dept-info.labri.u-bordeaux.fr/~vanicat
    • oliver@first.in-berlin.de
      ... [...] ... Well, and now I understand, why the bytecodecompiler warns me, that, when using a string-manipulating function, the function should have type
      Message 2 of 9 , Mar 5, 2003
      • 0 Attachment
        On Sat, Mar 01, 2003 at 03:47:19AM +0100, Remi Vanicat wrote:
        > oliver@...-berlin.de writes:
        >
        > > Hello,
        >
        > Hello,
        >
        > >
        > >
        > > that seems to be absolutely a beginners question,
        > > so I'm back to the Ocamlbeginners-mailinglist.
        > >
        > > Well, here is what I've done:
        > >
        > > =====================================================
        > > oliver@sam:~ > ocaml
        > > Objective Caml version 3.04
        > >
        > > # let l1 = [ "aaa"; "bbb"; "ccc"];;
        > > val l1 : string list = ["aaa"; "bbb"; "ccc"]
        > > # let l2 = l1;;
        > > val l2 : string list = ["aaa"; "bbb"; "ccc"]
        > > # (List.hd l2).[2] <- 'Z';;
        > > - : unit = ()
        > > # l1;;
        > > - : string list = ["aaZ"; "bbb"; "ccc"]
        > > # l2;;
        > > - : string list = ["aaZ"; "bbb"; "ccc"]
        > > #
        > > =====================================================
        > >
        > > Why are _both_ lists changed?
        [...]
        > > And much more pain and panic creates the next question:
        > >
        > > Why is it possible to change the list's contents?
        > > Shouldn't (List.hd l2) give back a result, which
        > > (only the result) is then afterwards changed?
        > > (That's, what I think would be functional programming!)
        >
        > No. functional programming would be to forbid any change. But O'Caml is
        > not purely functional, and an example of non functional part are
        > string, and in particular string manipulation.


        Well, and now I understand, why the bytecodecompiler warns me,
        that, when using a string-manipulating function, the function
        should have type unit.
        I used List.iter instead of List.map for applying the
        string-changer and no warnings were printed.

        I don't know why, but ocamlc has printed this warning,
        even if I had a return-type "string", but have used
        string-manipulation (in place changed).
        I first had the string as last value in the function
        (after a for-loop I added "; name" after the done-statement,
        and name was the changed string).


        So the function had type string -> string.

        Only looking at the types, I would think, that
        there will be no warning, because the types
        were ok.

        But nevertheless the ocamlc told me, that I better should use
        a unit-type for that function...

        So it has a higher iq than the is necessary for the typesystem.

        I had not awaited this.

        But step after step I more and more see, what's going on here.



        [...]
        > > If I would use Arrays here (instead of Lists) then I would
        > > be irritated, but not be shocked.
        > > Now, where I use lists and can change
        >
        > The list haven't been changed. They contain exactly the same strings
        > (the same block of memory). But this strings have changed.
        >
        > > them in an imperative way, I'm absolutely confused and shocked and
        > > irritated!
        > >
        > > So, I can create side effects by changing the data in this way?!
        >
        > changing data are side effect.
        >
        > When you are doing something like
        > (List.hd l2).[2] <- 'Z';;


        Well this mail from you is again worth printing on paper
        and read it more often and think and rethink about it,
        until I got it, what here is going on in Ocaml.

        Even if I can write small applications (well, better say
        scripts to that minimalistic stuff ;-)) I have many questions
        and see, that it's a long way, learning Ocaml.

        That it is using different programming paradigms sometimes
        is a littlebid confusing.





        >
        > This doesn't have any useful returned value. The result of this line
        > is the modification of a string. This is a side effect.
        >
        > If you want a side effect free language, try Haskell or Clean.


        Well, I had explored Haskell for a while.

        And maybe that's, why I'm looking for haskellism here.


        Ciao,
        Oliver
      • Remi Vanicat
        ... [...] ... I m not sure you ave understood. When you do something as : foo bar xux; wo um da the result of the evaluation of foo bar xux is thrown. It is
        Message 3 of 9 , Mar 5, 2003
        • 0 Attachment
          oliver@...-berlin.de writes:

          > On Sat, Mar 01, 2003 at 03:47:19AM +0100, Remi Vanicat wrote:

          [...]

          >> No. functional programming would be to forbid any change. But O'Caml is
          >> not purely functional, and an example of non functional part are
          >> string, and in particular string manipulation.
          >
          >
          > Well, and now I understand, why the bytecodecompiler warns me,
          > that, when using a string-manipulating function, the function
          > should have type unit.

          I'm not sure you ave understood.
          When you do something as :

          foo bar xux;
          wo um da

          the result of the evaluation of foo bar xux is thrown. It is
          possible, but strange (you are creating a value, and you throw it).
          So ocaml warn you.

          You should:

          bind the result of the evaluation if you want to use it as in

          let res = foo bar xux in
          wo um da

          or explicitly said that you only want the side effect of the function
          as in :

          ignore (foo bar xux);
          wo um da

          > I used List.iter instead of List.map for applying the
          > string-changer and no warnings were printed.

          It's normal, you are explicitly doing side effect with a List.iter (or
          if it is not a side effect, it is a no-op, so we imagine that it is
          side effect).


          [...]

          > Only looking at the types, I would think, that
          > there will be no warning, because the types
          > were ok.

          warning are not error. The type is correct, but there might be an
          error...

          [...]

          >> > If I would use Arrays here (instead of Lists) then I would
          >> > be irritated, but not be shocked.
          >> > Now, where I use lists and can change
          >>
          >> The list haven't been changed. They contain exactly the same strings
          >> (the same block of memory). But this strings have changed.
          >>
          >> > them in an imperative way, I'm absolutely confused and shocked and
          >> > irritated!
          >> >
          >> > So, I can create side effects by changing the data in this way?!
          >>
          >> changing data are side effect.
          >>
          >> When you are doing something like
          >> (List.hd l2).[2] <- 'Z';;
          >
          >
          > Well this mail from you is again worth printing on paper
          > and read it more often and think and rethink about it,
          > until I got it, what here is going on in Ocaml.

          well more precisely, any function may have an action by two mean :

          - by returning value, as in « let f x = x + 1 » Here there is no side
          effect, it's functional programing
          - by modifying the state of something, as in « let f x = x.[2] <- 'Z' »
          Here, there the action is not only in returned value (in fact, there
          is nothing interesting there), it is in the modification of an
          already existing value. This is side effect. (Well, there are other
          side effect, for example any I/O function are doing side effect).

          [...]


          --
          Rémi Vanicat
          vanicat@labri.u-bordeaux.fr
          http://dept-info.labri.u-bordeaux.fr/~vanicat
        • Nicolas Cannasse
          [...] ... BTW, lots of people use the syntax : let _ = foo bar xux in wo um da instead of ignore, but that s more dangerous, since ignore warn you from
          Message 4 of 9 , Mar 5, 2003
          • 0 Attachment
            [...]
            > You should:
            >
            > bind the result of the evaluation if you want to use it as in
            >
            > let res = foo bar xux in
            > wo um da
            >
            > or explicitly said that you only want the side effect of the function
            > as in :
            >
            > ignore (foo bar xux);
            > wo um da

            BTW, lots of people use the syntax :

            let _ = foo bar xux in
            wo um da

            instead of ignore, but that's more dangerous, since "ignore" warn you from
            partial applications while "let _" doesn't.
            and even if something ugly like :

            let f x =
            do_some_side_effet;
            (fun y -> something else)

            let _ = f x

            has *maybe* a meaning, most of the time ignoring results of partial
            applications does not make sense.

            Nicolas Cannasse
          • oliver@first.in-berlin.de
            ... Ooops? Why this? I thought, the result of the *last* term is thrown?! Well, hmhhh... ... I have looked into the OCaml-Book (O Reilley) again today (my
            Message 5 of 9 , Mar 5, 2003
            • 0 Attachment
              On Thu, Mar 06, 2003 at 03:22:27AM +0100, Remi Vanicat wrote:
              > oliver@...-berlin.de writes:
              >
              > > On Sat, Mar 01, 2003 at 03:47:19AM +0100, Remi Vanicat wrote:
              >
              > [...]
              >
              > >> No. functional programming would be to forbid any change. But O'Caml is
              > >> not purely functional, and an example of non functional part are
              > >> string, and in particular string manipulation.
              > >
              > >
              > > Well, and now I understand, why the bytecodecompiler warns me,
              > > that, when using a string-manipulating function, the function
              > > should have type unit.
              >
              > I'm not sure you ave understood.
              > When you do something as :
              >
              > foo bar xux;
              > wo um da
              >
              > the result of the evaluation of foo bar xux is thrown.

              Ooops?

              Why this?

              I thought, the result of the *last* term is thrown?!


              Well, hmhhh...



              > It is
              > possible, but strange (you are creating a value, and you throw it).

              I have looked into the OCaml-Book (O'Reilley) again
              today (my printed papers, maybe too old and buggy?),
              to clear this fact:


              "The first of hte typically imperative structures is
              the _sequence_. This permist the left-to-righ evaluation
              of a sequence of expressions separated by semicolons.

              +-----------------------+
              Syntax: | expr_1 ; ... ; expr_n |
              +-----------------------+

              A sequence of expressions is itself an expression,
              whose value is that of the last expresiion in the
              sequence (here expr_n). Nevertheless, all the
              expressions are evaluated, and in particular their
              side-effects are taken into account."

              (Developping Applications with Objective-Caml, page 79)



              > So ocaml warn you.
              >
              > You should:
              >
              > bind the result of the evaluation if you want to use it as in
              >
              > let res = foo bar xux in
              > wo um da

              I thought a let-binding is necessary for evaluation-order only
              in functional statements?!
              If I understand the Ocaml-book correctly, then a
              sequence automatically creates a known evaluation-order
              via the ";"-syntax.
              And when the last term is thrown, I'm right with
              my stuff, that I had written...

              Or maybe the Ocaml-book is buggy.



              #########################################################
              let conv_to_valid old_name =
              let name = String.copy old_name in (* localize in-place-modifikation *)
              let not_enclosed_with a x b =
              not (a <= x & x <= b)
              in
              for i = 0 to String.length name -1
              do
              let c = name.[i] in
              if
              not_enclosed_with 'a' c 'z' &&
              not_enclosed_with 'A' c 'Z' &&
              not_enclosed_with '0' c '9' &&
              c <> '_' && c <> '+' && c <> '-' && c <> ':' && c <> '.'
              then
              name.[i] <- '_';
              done; name
              #########################################################

              This has type string -> string.

              When I throw out the "; name" at the end of this code,
              I have type string -> unit


              Do I talking about the same as you do?
              Or did you mean an other aspect of that
              sequence-construct?
              Why should I use a let-statement here?


              But nevertheless, when I used it correctly typed,
              I got such warnings. Well, to be correct: it was
              a code-version before this above code, where I had not
              inserted the String.copy, when the compiler showed
              my the warning. I have not tested, if the compiler
              would throw it again here (with this localized
              side-effects).

              With the String.copy I wanted to localize the
              in-place-modification to that function and therefore
              eleminate the side-effects to grab out into the
              environment of the function.

              Now all modifications are done locally.
              So looked from the environment of that function
              onto it, it is functional, because no side-effects
              on outlier variables/bindeings are done.

              I hope you can second this.


              (In haskell I think, this trick would not be necessary and
              I (or the language) had to do a complete copy...
              but that's an other story.)






              >
              > or explicitly said that you only want the side effect of the function
              > as in :
              >
              > ignore (foo bar xux);
              > wo um da



              Well, in another function of the same program/script,
              I have this code here:



              #####################################################
              let file_exists filename =
              try
              ignore (Unix.stat filename) ; true
              with
              Unix.Unix_error(Unix.ENOENT,_,_) -> false
              #####################################################

              I hope this is accaptable code even for FPL-people.

              This function has string -> bool.

              But why is ignore necessarily to be used to the first argument?
              Is there a problem, when I have to different types in such
              a sequence? Is it *this*, what the compiler is worrying
              about?



              Here again I used, what is mentioned in the O'Reilley
              book as "sequence".

              It works here.


              Will this work always?


              >
              > > I used List.iter instead of List.map for applying the
              > > string-changer and no warnings were printed.
              >
              > It's normal, you are explicitly doing side effect with a List.iter (or
              > if it is not a side effect, it is a no-op, so we imagine that it is
              > side effect).

              But when the type is string -> string, why does the
              bytecodecompiler warns me, that this function should
              better be string -> unit?

              I mean, when it detects, that I'am doing imperative
              stuff, even if the type of my function does not
              reflect this, then it is very friendly, that the compiler
              tells me that.
              On the other hand, it may would be better, if it says
              that it's an error, and stops compiling.

              (But, as written in my last mail, I didn#t suspected, that
              the compiler knows, that it is a side-effecting function, because
              it gave me string -> string and so I thought I had "confused"
              him. But I had not. (?!))





              >
              >
              > [...]
              >
              > > Only looking at the types, I would think, that
              > > there will be no warning, because the types
              > > were ok.
              >
              > warning are not error. The type is correct, but there might be an
              > error...


              string -> string
              might be errorneous and should better be
              strig -> unit


              That is, what the compiler told me.

              Do you agree, that it is *this*, what he told me?




              >
              > [...]
              >
              > >> > If I would use Arrays here (instead of Lists) then I would
              > >> > be irritated, but not be shocked.
              > >> > Now, where I use lists and can change
              > >>
              > >> The list haven't been changed. They contain exactly the same strings
              > >> (the same block of memory). But this strings have changed.
              > >>
              > >> > them in an imperative way, I'm absolutely confused and shocked and
              > >> > irritated!
              > >> >
              > >> > So, I can create side effects by changing the data in this way?!
              > >>
              > >> changing data are side effect.
              > >>
              > >> When you are doing something like
              > >> (List.hd l2).[2] <- 'Z';;
              > >
              > >
              > > Well this mail from you is again worth printing on paper
              > > and read it more often and think and rethink about it,
              > > until I got it, what here is going on in Ocaml.
              >
              > well more precisely, any function may have an action by two mean :
              >
              > - by returning value, as in « let f x = x + 1 » Here there is no side
              > effect, it's functional programing

              OK, I see this.


              > - by modifying the state of something, as in « let f x = x.[2] <- 'Z' »
              > Here, there the action is not only in returned value (in fact, there
              > is nothing interesting there), it is in the modification of an
              > already existing value. This is side effect. (Well, there are other
              > side effect, for example any I/O function are doing side effect).

              OK, and doing it like in the function above with an

              let f x = (String.copy x).[2] <- 'Z'

              is imperative/side-effective, but with localized side-effects,
              so that it - from the outside of the black box - should
              behave like functional code.

              (Well this may is not very elegant, and possibly problems
              can creep in here, because I may forget to localize the
              side-effects...)



              Ciao,
              Oliver
            • Nicolas Cannasse
              ... Yes, it s true. But you re evaluating a term which is not used, so if you want to discard the result you have to tell the compiler that it s really want
              Message 6 of 9 , Mar 5, 2003
              • 0 Attachment
                > I thought, the result of the *last* term is thrown?!

                Yes, it's true.
                But you're evaluating a term which is not used, so if you want to discard
                the result you have to tell the compiler that it's really want you want to
                do. For example one could write :

                List.map print_endline my_list;

                but that will alloc and construct a whole list of "unit" elements, which is
                useless.
                So the compiler warn you have the result of the operation which is
                discarded.

                You can then remplace by :
                List.iter print_endline my_list

                Which does not construct a list, and is so more efficient.
                ( If you put ignore, the function is still called and the result built, but
                discarded )

                let ignore _ = () ( with a warning for partial applications )

                Nicolas Cannasse
              • Remi Vanicat
                ... Because of my bad english. I meant discarded, not thrown. Bye the way, I would say that the result of the last term is returned, not thrown. Sorry :( [...]
                Message 7 of 9 , Mar 6, 2003
                • 0 Attachment
                  oliver@...-berlin.de writes:

                  > On Thu, Mar 06, 2003 at 03:22:27AM +0100, Remi Vanicat wrote:
                  >> oliver@...-berlin.de writes:
                  >>
                  >> > On Sat, Mar 01, 2003 at 03:47:19AM +0100, Remi Vanicat wrote:
                  >>
                  >> [...]
                  >>
                  >> >> No. functional programming would be to forbid any change. But O'Caml is
                  >> >> not purely functional, and an example of non functional part are
                  >> >> string, and in particular string manipulation.
                  >> >
                  >> >
                  >> > Well, and now I understand, why the bytecodecompiler warns me,
                  >> > that, when using a string-manipulating function, the function
                  >> > should have type unit.
                  >>
                  >> I'm not sure you ave understood.
                  >> When you do something as :
                  >>
                  >> foo bar xux;
                  >> wo um da
                  >>
                  >> the result of the evaluation of foo bar xux is thrown.
                  >
                  > Ooops?
                  >
                  > Why this?
                  >
                  > I thought, the result of the *last* term is thrown?!

                  Because of my bad english. I meant discarded, not thrown.
                  Bye the way, I would say that the result of the last term is returned,
                  not thrown.

                  Sorry :(

                  [...]


                  >
                  >
                  >> So ocaml warn you.
                  >>
                  >> You should:
                  >>
                  >> bind the result of the evaluation if you want to use it as in
                  >>
                  >> let res = foo bar xux in
                  >> wo um da
                  >
                  > I thought a let-binding is necessary for evaluation-order only
                  > in functional statements?!
                  > If I understand the Ocaml-book correctly, then a
                  > sequence automatically creates a known evaluation-order
                  > via the ";"-syntax.

                  As I said, if you need the returned value you have to bind it.

                  [...]


                  > #########################################################
                  > let conv_to_valid old_name =
                  > let name = String.copy old_name in (* localize in-place-modifikation *)
                  > let not_enclosed_with a x b =
                  > not (a <= x & x <= b)
                  > in
                  > for i = 0 to String.length name -1
                  > do
                  > let c = name.[i] in
                  > if
                  > not_enclosed_with 'a' c 'z' &&
                  > not_enclosed_with 'A' c 'Z' &&
                  > not_enclosed_with '0' c '9' &&
                  > c <> '_' && c <> '+' && c <> '-' && c <> ':' && c <> '.'
                  > then
                  > name.[i] <- '_';
                  > done; name
                  > #########################################################
                  >
                  > This has type string -> string.

                  And it is corcet.

                  >
                  > When I throw out the "; name" at the end of this code,
                  > I have type string -> unit

                  Yes, but your function do some modification on an new string, then do
                  nothing with this string, so it have no use.

                  >
                  >
                  > Do I talking about the same as you do?
                  > Or did you mean an other aspect of that
                  > sequence-construct?
                  > Why should I use a let-statement here?

                  You don't need it here.

                  >
                  >
                  > But nevertheless, when I used it correctly typed,
                  > I got such warnings. Well, to be correct: it was
                  > a code-version before this above code, where I had not
                  > inserted the String.copy, when the compiler showed
                  > my the warning. I have not tested, if the compiler
                  > would throw it again here (with this localized
                  > side-effects).

                  The warning is not about side effect. It is aboout ';'
                  sequence. Actually, most (all) of the time ';' sequence do side
                  effect, but what is important is not sid effect, it is ';'
                  sequence. You have (often) side effect that are not in ';' sequence,
                  and then there is no warning.


                  [...]


                  >>
                  >> or explicitly said that you only want the side effect of the function
                  >> as in :
                  >>
                  >> ignore (foo bar xux);
                  >> wo um da
                  >
                  >
                  >
                  > Well, in another function of the same program/script,
                  > I have this code here:
                  >
                  >
                  >
                  > #####################################################
                  > let file_exists filename =
                  > try
                  > ignore (Unix.stat filename) ; true
                  > with
                  > Unix.Unix_error(Unix.ENOENT,_,_) -> false
                  > #####################################################
                  >
                  > I hope this is accaptable code even for FPL-people.
                  >
                  > This function has string -> bool.
                  >
                  > But why is ignore necessarily to be used to the first argument?
                  > Is there a problem, when I have to different types in such
                  > a sequence? Is it *this*, what the compiler is worrying
                  > about?

                  when you write « Unix.stat filename; true » you say : compute the stat
                  of the file, then discadr it and return true. There is a warning
                  because it seem strange that you have discaded such a computed
                  value. Bye using the function ingore, you explicitly wrtoe in your
                  code that you are discarding some value, so there will be no more
                  warning.

                  By the way, there is a file_exists function in the module Sys. You
                  should use it.

                  [...]


                  >>
                  >> > I used List.iter instead of List.map for applying the
                  >> > string-changer and no warnings were printed.
                  >>
                  >> It's normal, you are explicitly doing side effect with a List.iter (or
                  >> if it is not a side effect, it is a no-op, so we imagine that it is
                  >> side effect).
                  >
                  > But when the type is string -> string, why does the
                  > bytecodecompiler warns me, that this function should
                  > better be string -> unit?

                  Well I have give not exactly the good explanatin. It should be :
                  you are explicitly doing something which returned valued have no use
                  with List.iter.

                  [...]


                  >
                  >> - by modifying the state of something, as in « let f x = x.[2] <- 'Z' »
                  >> Here, there the action is not only in returned value (in fact, there
                  >> is nothing interesting there), it is in the modification of an
                  >> already existing value. This is side effect. (Well, there are other
                  >> side effect, for example any I/O function are doing side effect).
                  >
                  > OK, and doing it like in the function above with an
                  >
                  > let f x = (String.copy x).[2] <- 'Z'
                  >
                  > is imperative/side-effective, but with localized side-effects,
                  > so that it - from the outside of the black box - should
                  > behave like functional code.

                  Exactly.
                  Well, it's a no-op function, you should write :

                  let f x = let cp = String.copy x in x.[2] <- 'Z'; cp

                  but you were true.

                  >
                  > (Well this may is not very elegant, and possibly problems
                  > can creep in here, because I may forget to localize the
                  > side-effects...)

                  One have to use side effect for any efficient string processing. It is
                  not such a problem.

                  --
                  Rémi Vanicat
                  vanicat@labri.u-bordeaux.fr
                  http://dept-info.labri.u-bordeaux.fr/~vanicat
                • oliver@first.in-berlin.de
                  ... [...] When I have a function and bind a name to it, or it s appliaction. How much overhead would this produce? None? If I have let myfunc arg =
                  Message 8 of 9 , Mar 19, 2003
                  • 0 Attachment
                    On Sat, Mar 01, 2003 at 03:47:19AM +0100, Remi Vanicat wrote:
                    > oliver@...-berlin.de writes:
                    >
                    > > Hello,
                    >
                    > Hello,
                    >
                    > >
                    > >
                    > > that seems to be absolutely a beginners question,
                    > > so I'm back to the Ocamlbeginners-mailinglist.
                    > >
                    > > Well, here is what I've done:
                    > >
                    > > =====================================================
                    > > oliver@sam:~ > ocaml
                    > > Objective Caml version 3.04
                    > >
                    > > # let l1 = [ "aaa"; "bbb"; "ccc"];;
                    > > val l1 : string list = ["aaa"; "bbb"; "ccc"]
                    > > # let l2 = l1;;
                    > > val l2 : string list = ["aaa"; "bbb"; "ccc"]
                    > > # (List.hd l2).[2] <- 'Z';;
                    > > - : unit = ()
                    > > # l1;;
                    > > - : string list = ["aaZ"; "bbb"; "ccc"]
                    > > # l2;;
                    > > - : string list = ["aaZ"; "bbb"; "ccc"]
                    > > #
                    > > =====================================================
                    > >
                    > > Why are _both_ lists changed?
                    >
                    > Because there is only one list, as a
                    >
                    > # l1 == l2;;
                    >
                    > would have prove you.
                    >
                    > O'Caml share everything, unless you expressively make it otherwise.
                    >
                    > If you want l2 to be a copy of l1, you would have to do it like this:
                    [...]



                    When I have a function and bind a name to it, or it's appliaction.
                    How much overhead would this produce?
                    None?


                    If I have


                    let myfunc arg = some_definition arg (* my basic senseless function *)


                    (* three functions, that makes sense, because they provide
                    convenient names (reall mnemonics ;-)) *)

                    let blahblah = myfunc arg1
                    let blihblah = myfunc arg2
                    let bluhblih = myfunc arg3


                    (* for the lazy programmers, all the verbose function calls will
                    get this shortnames *)

                    let baba = blahblah
                    let biba = blihblah
                    let bubi = bluhblih


                    Will OCaml let the four-letter-functions be as fast as
                    if I had written them directly into the code as
                    myfunc arg1
                    myfunc arg2
                    myfunc arg3

                    or will there be runtime overhead because of dereferencing
                    some pointers, or will there be much more overhead?

                    When I see the design and the arguments on that design
                    (mutable strings etc. and new names point to the same
                    regions in memory by default) for higher performance,
                    is this also true, that it is used in functional
                    stuff?
                    Or will there be more lack of runtime, when I use
                    more definitions on already existing code?

                    And if there is a performance problem, how big will it
                    be? Are there differences between different name-bindings
                    and using modules instead of name-bindings with let-statements?

                    Ciao,
                    Oliver
                  Your message has been successfully submitted and would be delivered to recipients shortly.