Question

I found that sometimes I must give types explicitly for pattern variables, otherwise Rascal would not work as expected. The following session in the Console says it all:

rascal>data foo = bar(int);
ok

rascal>int x = 1;
int: 1

rascal>[x | bar(x) <- [bar(2), bar(3)]];
list[void]: []

rascal>[x | bar(int x) <- [bar(2), bar(3)]];
list[int]: [2,3]

Why did this happen?

Was it helpful?

Solution

In the current version of Rascal it is such that variables in patterns that exist in the surrounding scope are not matched and shadowed, but rather checked for equality.

So:

 <int x, x> := <2,2> => true // x is first introduced and then checked for equality
 <int x, x> := <2,3> => false // x is first introduced and then checked for equality

 { int x = 1; if (x := 2) println("true"); else println("false"); // false!

And this holds for all places where we use pattern matching.

We have had several complaints about this particular design of "non-linear matching", and we intend to add an operator soon ($) to identify the intention of taking something from the surround scope. If the operator is not used, then shadowing will occur:

 <int x, $x> := <2,2> => true // x is first introduced and then checked for equality
 <int x, $x> := <2,3> => false // x is first introduced and then checked for equality
 <int x, x> := <2,3>  // static error due to illegal shadowing
 <int x, y> := <2,3> => true // x and y are both introduced

 { int x = 1; if ($x := 2) println("true"); else println("false"); // false!
 { int x = 1; if (x := 2) println("true <x>"); else println("false"); // true, prints 2! or perhaps a static error.

Might also add some additional power to get expressions into patterns as in:

 <1, ${1 + 2 + 3}> := <1,6> // true
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top