2

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?

day
  • 2,292
  • 1
  • 20
  • 23

1 Answers1

3

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
Jurgen Vinju
  • 6,393
  • 1
  • 15
  • 26