Add tests for infinite looping by writing code that times out
First I was going to suggest modifying the interpreter to have a "fuel" counter (in the style of some contemporary "smart contract" evaluators), but then I realized that this can probably be expressed in pure Bel, using threads and a modicum of cleverness. Stay tuned.
A lot of functions are susceptible to infinite looping when fed cyclic lists. We should give each of them a test.
[...] but then I realized that this can probably be expressed in pure Bel, using threads and a modicum of cleverness. Stay tuned.
Here's the general principle, nicely formatted for readability:
> (do
(set aborted nil)
(thread
(let n 0
(while (< (++ n) 5))
(set aborted t)
(pr 'aborted \lf)))
; meanwhile, in the main thread...
(let n 0
(while (and (no aborted)
(< (++ n) 1000))
(prn n))))
1
2
3
4
aborted
5
nil
> (do
(set aborted nil)
(thread
(do
(repeat 20)
(set aborted t)))
; meanwhile, in the main thread
(catch
(let n 0
(while (< (++ n) 1000)
(if aborted (throw 'aborted))
(prn n)))))
1
2
3
4
5
6
aborted
I just got a better idea — which I added to the (private) bel-masak-prelude repo as bind-fn/call-limit and bind-fn/timeout.
It would be sweet to be able to use those functions in the tests. I guess in the short term it will be easier to declare them in the test file.