local fun {PingPong Message MyDelay} fun {Ping N} if N==0 then {Browse Message#' terminated'} nil else {Delay MyDelay} Message|{Ping N-1} end end in Ping end in {Browse 'game started'} {Browse thread {{PingPong ping 500} 49} end} {Browse thread {{PingPong pong 600} 49} end} end declare fun {NewTicker} fun {Loop} X={OS.localTime} in {Delay 1000} % total delay is 1000 + epsilon milliseconds X|{Loop} end in thread {Loop} end end thread for X in {NewTicker} do {Browse X} end end declare fun {NewTicker} fun {Loop T} X={OS.localTime} in {Delay 900} % to avoid occasional loss of a second if X\=T then X|{Loop X} else {Loop X} end % guarantee no more than 1/s end in thread {Loop {Os.localTime}} end end thread for X in {NewTicker} do {Show X} end end % Above version will happen AT LEAST once per second IF % delay is always less than 1 s % It depends on 1) not too many active threads % 2) garbage collection not taking too long % % #1 can be guaranteed by giving Ticker alone highest priority % #2 can be ensured by programmer not having too much active data % Previous solution "hiccoughs" % Use shorter delay of 100ms ?? % Last solution below declare fun {NewTicker} fun {Loop N} T={Time.time} in if T>N then {Delay 900} elseif T