Search code examples
ocamlutop

Why is `;;` giving me a syntax error in utop?


I'm working on a short project to convert small programs from python to java and visa versa. I created the following code, and tested it in utop.

let c = 
let x = "for (int i = 0; i<10; i++)" 
and y = "for i in range(0,10):"
in function
| x -> y
| y -> x
| _ -> "Oh no!!";;

For some reason, x & y are both considered unbound, yet at the same time any parameter seems to match to x.

What order does everything need to be written in to make this work?


Solution

  • Simply to follow up with your answer.

    In pattern-matching, matching to a variable doesn't necessarily seem to match to its value.

    This is the very reason why it's called pattern-matching and not value-matching.

    As the name implies, pattern-matching is used to match things against patterns, not values. In the code you show in the question, you are not actually comparing anything to x or y, you are defining patterns named x and y that can match anything. See the example below:

    match 2 with
    | x -> "Hey, I matched!"
    | _ -> "Oh, I didn't match.";;
    
    - : string = "Hey, I matched!"
    

    Note that this works even if x was previously defined. In the match case, the x from the pattern is actually shadowing the other one.

    let x = 42 in
    match 1337 with
    | x -> Printf.printf "Matched %d\n!" x
    | _ -> ();;
    
    Matched 1337!
    - : unit = ()
    

    On the other hand, the pattern i when i = x is actually matching against the value of the outer variable x, which is why the code in your self-answer works. But this is not what patterns are for anyway.

    What you're actually trying to do is not a pattern-matching, it is a simple conditional statement.

    let c argument = 
      let x = "for (int i = 0; i<10; i++)"  in
      let y = "for i in range(0,10):" in
      if argument = x then y
      else if argument = y then x
      else "Oh no!";;
    
    val c : string -> string = <fun>
    

    And here it is in action:

    c "for (int i = 0; i<10; i++)";;
    - : string = "for i in range(0,10):"
    
    c "for i in range(0,10):";;
    - : string = "for (int i = 0; i<10; i++)"
    
    c "whatever";;
    - : string = "Oh no!"
    

    Also, don't use and unless you're defining mutually recursive values.