Whats going on here? let (x,y) = ((((1,2))))

Just when I think I’m starting to understand things.

let x = Js.Math.random_int(0,9)
let y = Js.Math.random_int(0,9)
let (x,y) = ((((x,y))))
Js.log(x+y) //=> some int

Compiles to

var x = Js_math.random_int(0, 9);
var y = Js_math.random_int(0, 9);
console.log(x + y | 0)

First, x is bound to a random int.

Then, y is bound to a random int.

Then, a pattern (x, y) is bound to the tuple (x, y). When a pattern is bound, the variables in the pattern are given the corresponding values on the right hand side. So basically, x and y are bound to themselves, which is a no-op.

Finally, you log the sum of x and y.

2 Likes

All that is obvious to me, and I used random so the compiler wouldn’t optimize everything away and I could look at the generated JS. But you completely glossed over 4 pairs of matching parens on the right side.

to me, destructuring like this

let (x,y) = (1,2)

makes sense, but something else is afoot when this works

let (x,y) = ((((((((((1,2)))))))))))

Extra parentheses are no-ops in ReScript, just like they are in JavaScript. 1 is equal to (1), and equal to (((1))). The formatter removes the extra parentheses for this reason.

1 Like

I glossed over that because you didn’t highlight that it was your confusion. Other people don’t know exactly what’s in your mind :wink:

1 Like

In JS they are probably a no-op because it was a case of JS accommodating everything the user typed, whether it made sense or not :slight_smile:

But how about this: in ReScript, since there are no single element tuples, hence

(1) == 1

then

((((1,2)))) == (((1,2))) == (((1,2)) == ((1,2)) == (1,2)

This is why it’s important to use the formatter IMO, it clears up that () is a no-op in this scenario almost as soon as you type it.

let x = ((1, 2));

// formatted:
let x = (1, 2);
1 Like

In the case of (1), the way it is parsed has nothing to do with tuples. It’s doing the same thing as JavaScript: grouping expressions together to control precedence. It’s why this 2 + 3 * 4 is different than this (2 + 3) * 4. Just like JavaScript, there’s nothing stopping you from adding extra parentheses around an expression, even if they’re superfluous.

2 Likes

Can you be sure?

These both work in rescript

let x = (1)
let (x) = (1)

But they both don’t work in JS

let x = (1)
let (x) = (1) // SyntaxError: Unexpected strict mode reserved word

Makes me wonder if more than simple parsing is going on.

It’s a syntax error because JavaScript can’t understand parentheses around a variable name on the left hand side. In ReScript it’s parsed and discarded. It has nothing to do with tuples. You can verify this by trying let x = (1) in ReScript. It has a type x : int. Just a simple int, no tuples.

1 Like