- 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] - 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 =

Which is very fun since there are only 5 lines. Also, the code above uses what

> 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

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]