2

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?

Mark Puchala II
  • 634
  • 2
  • 8
  • 25
  • 2
    [Don't post screenshots of text](https://meta.stackoverflow.com/questions/303812/discourage-screenshots-of-code-and-or-errors). Copy-paste the code. – Gilles 'SO- stop being evil' Dec 02 '17 at 21:14
  • 1
    You wrote `let … in let …`, that doesn't make sense. If you wanted to define `c` at the top level, you need to start with `let c = …`. If you wanted to define `c` in a single expression, the expression is missing. – Gilles 'SO- stop being evil' Dec 02 '17 at 21:15
  • @Gilles I tried to copy-paste the code in, but couldn't find a way to illustrate that utop was underscoring the ;;. Do you know how to do that? – Mark Puchala II Dec 02 '17 at 21:20
  • @Gilles I tried beginning with `let c = ` before `let x = " " and y = " " in`, but this left x & y unused for the match case. – Mark Puchala II Dec 02 '17 at 21:23
  • Assuming that you want the `function` to be returned, you either have to use `let c = ... in c;;` or remove `let c =` . The reason is, if all you have are `let` expressions, what is the result type of the your snippet? – BahmanM Dec 03 '17 at 07:46
  • Also, you dont seem to understand how patter-matching works. In your example it will always enter the first case. You can read this to understand why: https://stackoverflow.com/questions/17674549/pattern-matching-a-variable-in-ocaml – ghilesZ Dec 03 '17 at 09:25
  • Whoever down voted my question, could you explain why? – Mark Puchala II Dec 03 '17 at 20:08
  • @ghilesZ I believe you're right I don't seem to fully understand pattern-matching, and that's why I'm here asking about it. Your link seemed to get my code to work. Thanks for your help! I'm writing it up as an answer, now. – Mark Puchala II Dec 03 '17 at 20:09

2 Answers2

2

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.

Richard-Degenne
  • 2,892
  • 2
  • 26
  • 43
0

So I'm not fully understanding WHY it works this way, but I at least understand how it works.

My issue was that, in pattern-matching, matching to a variable doesn't necessarily seem to match to its value.

In short, I should be typing

 function
 | i when i = x -> y
 | i when i = y -> x
 | _ -> "Oh no!!";;

If anyone can shed some more light on what differentiates "x -> y" from I when I = x -> y, I am still curious about that.

Otherwise, thanks @ghilesZ for sending me the links I needed to figure this one out! And thanks @BahmanMovaqar for helping me understand the priority of statements a bit better.

Mark Puchala II
  • 634
  • 2
  • 8
  • 25