You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here we find a simple sequence comprehension that exhibits exponential runtime when Cryptol defaults a type, though when we explicitly type the sequence (to the same that Cryptol defaulted the sequence to) we see the expected linear time runtime. The traceVal is added to more easily demonstrate this odd behavior, but the behavior happens w/out it (feel free to remove traceVal and experience the runtime with both fibs@20. I could not get fibs@30 (with defaulting) to even finish.)
Main> let fibs = [0, 1] # [ traceVal "a + b" (a + b) | a <- fibs | b <- tail fibs ]
Main> fibs@6
Showing a specific instance of polymorphic result:
* Using 'Integer' for 1st type argument of '<interactive>::fibs'
a + b 1
a + b 1
a + b 2
a + b 3
a + b 1
a + b 2
a + b 1
a + b 1
a + b 2
a + b 3
a + b 5
a + b 8
8
Main> let fibs = [0:Integer, 1] # [ traceVal "a + b" (a + b) | a <- fibs | b <- tail fibs ]
Main> fibs@6
a + b 1
a + b 2
a + b 3
a + b 5
a + b 8
8
The text was updated successfully, but these errors were encountered:
So, that's not exactly a bug, although clearly it's undesirable.
The issue is that even though the first fiblooks like a value, it is a polymorphic value, and as such it is actually a function of the type (note the fibs can behave quite differently depending on what type it is instantiated with, for example try fibs`{[1]}).
In contrast, the second example is indeed just an ordinary value and it would be cached, as expected.
Note that the defaulting that's happening here is too late---fibs is still a polymorphic function, the defaulting just provides its type parameter: we do not, however, rewrite the body of the function, it is still a polymorphic function.
This is an issue in Haskell too, and the choice the designers made in that context is to have the "monomorphism restriction", which says that things that don't look like functions (e.g., fibs above) cannot be polymorphic, unless they have an explicit type signature, so that it is obvious what's happening. While we could implement some such thing, the experience with Haskell has been that this restriction can be quite annoying, and folks tend to disable it. This is likely to be even more the case in Cryptol, where being polymorphic in numeric types is quite common.
I think we have a few possible choices:
A) Easiest: emit a warning when something looks like a value but is actually a function, and there is no explicit type signature (so like a "weak" monomorphism restriction)
B) Medium: like (A) but instead of issuing a warning default the definition if possible, so it would become automatically monomorphic
C) Most complicated: modify the interpreter to somehow cache functions that only have type arguments.
My vote would be for (A) or (B), because replicating (C) would be pretty hard to do in the Cryptol compiler
Here we find a simple sequence comprehension that exhibits exponential runtime when Cryptol defaults a type, though when we explicitly type the sequence (to the same that Cryptol defaulted the sequence to) we see the expected linear time runtime. The
traceVal
is added to more easily demonstrate this odd behavior, but the behavior happens w/out it (feel free to removetraceVal
and experience the runtime with bothfibs@20
. I could not getfibs@30
(with defaulting) to even finish.)The text was updated successfully, but these errors were encountered: