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

simple if-then-else question

Expand Messages
  • Mac Brown
    This is a very beginner question. I don t see why the following simple code doesn t compile. 1  let eq a b = 2  let r = ref false in 3  if a = b then  r :=
    Message 1 of 9 , Jul 29, 2009
    • 0 Attachment
      This is a very beginner question. I don't see why the following simple code doesn't compile.

      1  let eq a b =
      2  let r = ref false in
      3  if a = b then  r := true;  ()
      4  else r := false;  ()
      5  r ;;

      [ocaml] $ ocaml ifelse.ml
      File "ifelse.ml", line 6, characters 1-5:
      Error: Syntax error

      Can someone explain what I am doing wrong?

      Thanks for your help,


      Mac






      [Non-text portions of this message have been removed]
    • Cedric Cellier
      -[ Wed, Jul 29, 2009 at 10:33:07PM -0700, Mac Brown ]---- ... Which is very fun since there are only 5 lines. Also, the code above uses what seams to be
      Message 2 of 9 , Jul 29, 2009
      • 0 Attachment
        -[ Wed, Jul 29, 2009 at 10:33:07PM -0700, Mac Brown ]----
        > 1  let eq a b =
        > 2  let r = ref false in
        > 3  if a = b then  r := true;  ()
        > 4  else r := false;  ()
        > 5  r ;;
        >
        > [ocaml] $ ocaml ifelse.ml
        > File "ifelse.ml", line 6, characters 1-5:
        > Error: Syntax error

        Which is very fun since there are only 5 lines. Also, the code above uses what
        seams to be unicode non breakable spaces. ocaml will choke with them. So I
        assume they were added by your mail client.

        Once cleaned, I got :

        File "ifelse.ml", line 4, characters 0-4: Syntax error

        meaning it doesn't expected to see an else keyword
        dangling here.

        The syntax of an if-then-else is basicaly :

        if boolean_something then something1 else something1

        where something1 and something2 must have the same type, and with this whole
        if-then-else expression having this very type.

        When something is a single expression, just write it. If it's a sequence of
        subexpressions, then write the subexpressions separated with a semi-colon and
        surrounded by parens, like this :

        if bool_expr then (a; b; c) else (d; e; f)

        If you forget the parens you have this :

        if bool_expr then a; b; c else d; e; f

        then Ocaml think the first subexpression is "if bool_expr then a" then the
        second "b" then "c else d" which is meaningless thus gives the above syntax
        error.

        So, adding the parens fix this problem :

        $ cat >ifelse2.ml <<EOF
        let eq a b =
        let r = ref false in
        if a = b then (r := true; ())
        else (r := false; ())
        r ;;
        EOF
        $ ocaml ifelse.ml
        File "ifelse.ml", line 4, characters 5-21:
        This expression is not a function, it cannot be applied

        Now what ? We now have :

        if bool_expr then (expressions) else (expressions)
        r;;

        That we can rewrite like this since the new line is equivalent to a space :

        if bool_expr then (expressions) else (expressions) r;;

        See ? The else-part is actualy "(expressions) r", which means : apply the
        function (expressions) to parameter r.

        So we need to separate the if-then-else expression from the "r" expression,
        again with a semi-colon :

        $ cat >ifelse2.ml <<EOF
        let eq a b =
        let r = ref false in
        if a = b then (r := true; ())
        else (r := false; ());
        r ;;
        EOF
        $ ocaml ifelse.ml

        OK !
        Now some notes :

        1) try to provide a minimal indentation
        2) when you want to "cast" an expression to unit type, better use
        "ignore(expr)" than "(expr; ())"
        3) you don't have to cast an affectation to the unit type anyway since
        affectations like "r := true" already have unit type
        4) the final ";;" seams useless to me (and to the compiler)

        This whole thing could then be rewritten :

        let eq a b =
        let r = ref false in
        if a = b then r := true else r := false;
        r

        Or without the ref :

        let eq a b =
        if a = b then true else false

        Or aliasing = :

        let eq a b = (=)

        But then there is not enough syntax left to learn something :-)

        Don't give up !
        I'm myself a newby that was disapointed by Ocaml's syntax not so long ago.
        To my surprise the syntax ceased to be a problem after only a few days.
      • Ashish Agarwal
        You need parentheses to get it to compile correctly, and also you need to end the if..then..else with a semicolon. The following compiles: let eq a b = let r =
        Message 3 of 9 , Jul 30, 2009
        • 0 Attachment
          You need parentheses to get it to compile correctly, and also you need to
          end the if..then..else with a semicolon. The following compiles:
          let eq a b =
          let r = ref false in
          if a = b then (r := true; ())
          else (r := false; ())
          ;
          r;;

          However, your code could be simplified to:

          let eq a b =
          let r = ref false in
          if a = b then r := true
          else r := false
          ;
          r;;

          because the return value of "r := true" and "r := false" is already unit. So
          there is no reason to discard that value and then return unit anyway.



          On Thu, Jul 30, 2009 at 1:33 AM, Mac Brown <macbrowny@...> wrote:

          >
          >
          > This is a very beginner question. I don't see why the following simple code
          > doesn't compile.
          >
          > 1 let eq a b =
          > 2 let r = ref false in
          > 3 if a = b then r := true; ()
          > 4 else r := false; ()
          > 5 r ;;
          >
          > [ocaml] $ ocaml ifelse.ml
          > File "ifelse.ml", line 6, characters 1-5:
          > Error: Syntax error
          >
          > Can someone explain what I am doing wrong?
          >
          > Thanks for your help,
          >
          > Mac
          >
          > [Non-text portions of this message have been removed]
          >
          >
          >


          [Non-text portions of this message have been removed]
        • Florent Monnier
          ... this one won t work because it makes partial application # let eq a b = ( = ) ;; val eq : a - b - c - c - bool = # eq 34 45 ;; - : _a - _a
          Message 4 of 9 , Jul 30, 2009
          • 0 Attachment
            > let eq a b = (=)

            this one won't work because it makes partial application

            # let eq a b = ( = ) ;;
            val eq : 'a -> 'b -> 'c -> 'c -> bool = <fun>
            # eq 34 45 ;;
            - : '_a -> '_a -> bool = <fun>
            # eq "hello" 4.9562937 22 22 ;;
            - : bool = true

            # let eq a b =
            (a = b)
            ;;
            val eq : 'a -> 'a -> bool = <fun>
            # eq 34 45 ;;
            - : bool = false

            # let eq = ( = ) ;;
            val eq : 'a -> 'a -> bool = <fun>
            # eq 3 3 ;;
            - : bool = true
          • Cedric Cellier
            -[ Thu, Jul 30, 2009 at 03:49:50PM +0200, Florent Monnier ]---- ... Soory, I just checked that it compiled. Damnd, I was sold ocaml because once it compiles,
            Message 5 of 9 , Jul 30, 2009
            • 0 Attachment
              -[ Thu, Jul 30, 2009 at 03:49:50PM +0200, Florent Monnier ]----
              > > let eq a b = (=)
              >
              > this one won't work because it makes partial application

              Soory, I just checked that it compiled.

              Damnd, I was sold ocaml because "once it compiles, it works!" :-)
            • Ashish Agarwal
              Unfortunately, there is no warning when function arguments are not used. # let f a = let x = 3 in 5;; Warning Y: unused variable x. val f : a - int =
              Message 6 of 9 , Jul 30, 2009
              • 0 Attachment
                Unfortunately, there is no warning when function arguments are not used.
                # let f a = let x = 3 in 5;;
                Warning Y: unused variable x.
                val f : 'a -> int = <fun>

                You are warned about not using x, but no such warning for a.


                On Thu, Jul 30, 2009 at 9:59 AM, Cedric Cellier <rixed@...>wrote:

                >
                >
                > -[ Thu, Jul 30, 2009 at 03:49:50PM +0200, Florent Monnier ]----
                >
                > > > let eq a b = (=)
                > >
                > > this one won't work because it makes partial application
                >
                > Soory, I just checked that it compiled.
                >
                > Damnd, I was sold ocaml because "once it compiles, it works!" :-)
                >
                >
                >


                [Non-text portions of this message have been removed]
              • ygrek
                On Thu, 30 Jul 2009 11:42:07 -0400 ... $ ocaml -w Z Objective Caml version 3.11.0 # let f a = let x = 3 in 5;; Warning Y: unused variable x. Warning Z: unused
                Message 7 of 9 , Jul 30, 2009
                • 0 Attachment
                  On Thu, 30 Jul 2009 11:42:07 -0400
                  Ashish Agarwal <agarwal1975@...> wrote:

                  > Unfortunately, there is no warning when function arguments are not used.
                  > # let f a = let x = 3 in 5;;
                  > Warning Y: unused variable x.
                  > val f : 'a -> int = <fun>
                  >
                  > You are warned about not using x, but no such warning for a.

                  $ ocaml -w Z
                  Objective Caml version 3.11.0

                  # let f a = let x = 3 in 5;;
                  Warning Y: unused variable x.
                  Warning Z: unused variable a.
                  val f : 'a -> int = <fun>

                  --
                  ygrek
                • Peng Zang
                  ... Hash: SHA1 Awesome, I ve been looking for that. Thanks! Peng ... Version: GnuPG v2.0.7 (GNU/Linux)
                  Message 8 of 9 , Jul 30, 2009
                  • 0 Attachment
                    -----BEGIN PGP SIGNED MESSAGE-----
                    Hash: SHA1

                    Awesome, I've been looking for that. Thanks!

                    Peng

                    On Thursday 30 July 2009 02:33:29 pm ygrek wrote:
                    > On Thu, 30 Jul 2009 11:42:07 -0400
                    >
                    > Ashish Agarwal <agarwal1975@...> wrote:
                    > > Unfortunately, there is no warning when function arguments are not used.
                    > > # let f a = let x = 3 in 5;;
                    > > Warning Y: unused variable x.
                    > > val f : 'a -> int = <fun>
                    > >
                    > > You are warned about not using x, but no such warning for a.
                    >
                    > $ ocaml -w Z
                    > Objective Caml version 3.11.0
                    >
                    > # let f a = let x = 3 in 5;;
                    > Warning Y: unused variable x.
                    > Warning Z: unused variable a.
                    > val f : 'a -> int = <fun>
                    -----BEGIN PGP SIGNATURE-----
                    Version: GnuPG v2.0.7 (GNU/Linux)

                    iD8DBQFKcesWfIRcEFL/JewRAjlwAJ9MWeBFW/bUEXSlU66HTkREIKz6PQCeO3AR
                    I3Nj7gED/ZLLJd+dxWabIoM=
                    =c7ah
                    -----END PGP SIGNATURE-----
                  • Mac Brown
                    Thanks a lot for your replies, folks! Special thanks to Cedric for such a detailed explanation and some tips. -Mac ________________________________ From:
                    Message 9 of 9 , Jul 30, 2009
                    • 0 Attachment
                      Thanks a lot for your replies, folks! Special thanks to Cedric for such a detailed explanation and some tips.

                      -Mac







                      ________________________________
                      From: Cedric Cellier <rixed@...>
                      To: ocaml_beginners@yahoogroups.com
                      Sent: Thursday, July 30, 2009 2:44:38 AM
                      Subject: "ocaml_beginners"::[] simple if-then-else answer


                      -[ Wed, Jul 29, 2009 at 10:33:07PM -0700, Mac Brown ]----
                      > 1 let eq a b =
                      > 2 let r = ref false in
                      > 3 if a = b then r := true; ()
                      > 4 else r := false; ()
                      > 5 r ;;
                      >
                      > [ocaml] $ ocaml ifelse.ml
                      > File "ifelse.ml", line 6, characters 1-5:
                      > Error: Syntax error

                      Which is very fun since there are only 5 lines. Also, the code above uses what
                      seams to be unicode non breakable spaces. ocaml will choke with them. So I
                      assume they were added by your mail client.

                      Once cleaned, I got :

                      File "ifelse.ml", line 4, characters 0-4: Syntax error

                      meaning it doesn't expected to see an else keyword
                      dangling here.

                      The syntax of an if-then-else is basicaly :

                      if boolean_something then something1 else something1

                      where something1 and something2 must have the same type, and with this whole
                      if-then-else expression having this very type.

                      When something is a single expression, just write it. If it's a sequence of
                      subexpressions, then write the subexpressions separated with a semi-colon and
                      surrounded by parens, like this :

                      if bool_expr then (a; b; c) else (d; e; f)

                      If you forget the parens you have this :

                      if bool_expr then a; b; c else d; e; f

                      then Ocaml think the first subexpression is "if bool_expr then a" then the
                      second "b" then "c else d" which is meaningless thus gives the above syntax
                      error.

                      So, adding the parens fix this problem :

                      $ cat >ifelse2.ml <<EOF
                      let eq a b =
                      let r = ref false in
                      if a = b then (r := true; ())
                      else (r := false; ())
                      r ;;
                      EOF
                      $ ocaml ifelse.ml
                      File "ifelse.ml", line 4, characters 5-21:
                      This expression is not a function, it cannot be applied

                      Now what ? We now have :

                      if bool_expr then (expressions) else (expressions)
                      r;;

                      That we can rewrite like this since the new line is equivalent to a space :

                      if bool_expr then (expressions) else (expressions) r;;

                      See ? The else-part is actualy "(expressions) r", which means : apply the
                      function (expressions) to parameter r.

                      So we need to separate the if-then-else expression from the "r" expression,
                      again with a semi-colon :

                      $ cat >ifelse2.ml <<EOF
                      let eq a b =
                      let r = ref false in
                      if a = b then (r := true; ())
                      else (r := false; ());
                      r ;;
                      EOF
                      $ ocaml ifelse.ml

                      OK !
                      Now some notes :

                      1) try to provide a minimal indentation
                      2) when you want to "cast" an expression to unit type, better use
                      "ignore(expr) " than "(expr; ())"
                      3) you don't have to cast an affectation to the unit type anyway since
                      affectations like "r := true" already have unit type
                      4) the final ";;" seams useless to me (and to the compiler)

                      This whole thing could then be rewritten :

                      let eq a b =
                      let r = ref false in
                      if a = b then r := true else r := false;
                      r

                      Or without the ref :

                      let eq a b =
                      if a = b then true else false

                      Or aliasing = :

                      let eq a b = (=)

                      But then there is not enough syntax left to learn something :-)

                      Don't give up !
                      I'm myself a newby that was disapointed by Ocaml's syntax not so long ago.
                      To my surprise the syntax ceased to be a problem after only a few days.







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