nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.62k stars 1.47k forks source link

36 activations of term rewriting macro? #9288

Open kaushalmodi opened 6 years ago

kaushalmodi commented 6 years ago

I took an example from the Nim Manual's TRM section: https://nim-lang.org/docs/manual.html#term-rewriting-macros

The example is almost as-is except that I added a debugEcho so that I know if/when the TRM is getting activated:

template mulIsCommutative{`*`(a, b)}(a, b: int): int =
  debugEcho("-> Term rewriting activated!")
  b * a

let x = 3
echo "Calculating x * 2:"
echo x * 2

Surprisingly that prints:

Calculating x * 2:
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
6

Ref: https://gitter.im/nim-lang/Nim?at=5bbe2eb6bbdc0b25051a4d02

what happens is that diverging rewrite rules get cancelled at some point - Araq

/cc @Araq

kaushalmodi commented 6 years ago

To add to the complication, if I add another multiplication after that first one, the TRM stops activating altogether:

template mulIsCommutative{`*`(a, b)}(a, b: int): int =
  debugEcho("-> Term rewriting activated!")
  b * a

let x = 3
echo "Calculating x * 2:"
echo x * 2

echo ""
echo "Calculating x * 2 again:"
echo x * 2

echo ""
echo "Calculating x * 3:"
echo x * 3

Output:

Calculating x * 2:
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
-> Term rewriting activated!
6

Calculating x * 2 again:
6

Calculating x * 3:
9
andreaferretti commented 6 years ago

Duplicate of https://github.com/nim-lang/Nim/issues/8376 and https://github.com/nim-lang/Nim/issues/2901

andreaferretti commented 6 years ago

The confusion stems from the fact that term rewriting macros are applied recursively (up to a limit). I think this should be documented in the manual and all 3 issues closed

kaushalmodi commented 6 years ago

(up to a limit).

That limit is 36?

I think this should be documented in the manual and all 3 issues closed

I can understand that for the first multiplication overflow happened, and TRM stopped activating after 36 loops. But then why does it not get activated at all for the next 2 multiplications? Once the limit is reached, the TRM stops working altogether for the rest of the program?

andreaferretti commented 6 years ago

I presume so, according to your experiments

kaushalmodi commented 6 years ago

It would be more ensuring to get a better answer. "presume so" sounds like you also don't know for sure if that's the case. I'd like to know the answers to my 3 questions based on spec or design choice rather than based on my toy example.