# Internal “Periodical” functions in version 7

In version 7 there exist these Internal context functions:

?Internal*Periodical*


AddPeriodical   Periodicals   RemovePeriodical   $ThisPeriodical In a comment to this answer Szabolcs stated that these "seem to provide very similar (the same?) functionality" to ScheduledTasks in version 8. • How do I use them? • To what extent is is possible to mimic version 8 functionality using these? - ## 2 Answers As a starting point I'll write up what I found about these functions before. I'm hoping someone will take a better look at them and will write a more complete answer. Spelunking in version 8, InternalAddPeriodical[Print["boo!"], 3]  Now you get a boo! every 3 seconds. InternalPeriodicals[] (* ==> {Print["boo!"]} *)  Now do InternalRemovePeriodical[Print["boo!"]]  to stop it. InternalPeriodicals[] (* ==> {} *)  Note that AddPeriodical and RemovePeriodical have HoldFirst. Internal$ThisPeriodical seems to be undefined during normal evaluations, while it is set to the currently executing periodical (wrapped in HoldForm) when a periodical is being executed.

Most (all?) of the version 8 functionality seems to be implementable in terms of these, provided that they work the same way in version 7 as in 8 (which I cannot test).

-
Or, more annoyingly: InternalAddPeriodical[Speak["boo!"], 3] but just be sure you're ready to invoke InternalRemovePeriodical[Print["boo!"]] before going nuts! – murray Mar 11 '12 at 22:08
@murray Nooo, you have to do InternalRemovePeriodical[Speak["boo!"]] – Ajasja Jul 16 '12 at 7:58

You can turn this then into a package, and change the lower-case to uppercase... Hope it works well enough for your goals. If not, we'll improve it in time

AppendTo[$ContextPath, "Internal"]; ClearAll["private*"]; SetAttributes[privatecount, HoldRest]; privatecount[_, expr_, count_Symbol][id_, ___] /; Block[{$scheduledTask = privategetST[id]}, expr; ++count]/;False := Null
e : privatecount[i_, _, count_Symbol][id_, endFun : _ : (Null &)] /;
count === i := (Remove[count]; RemovePeriodical[e]; endFun[])
privatecount[___][___] := Null

privategetST[id_] /;
privategetST[_] := $Failed; privateSTQ[scheduledTaskObject[id_, expr_, time_, start_, _]] := Length[Cases[scheduledTasks[]/. HoldPattern@\[Infinity] -> \[Infinity], scheduledTaskObject[id, expr, time, start, _]/. HoldPattern@\[Infinity] -> \[Infinity]]] >= 1 privateSTQ[___] := False; privatestartScheduledTask[ st : scheduledTaskObject[id_, expr_, {time_, count_}, (start_ /; start <= AbsoluteTime[]) | Automatic, _]] := Module[{counter = 0}, ClearAttributes[counter, Temporary]; AddPeriodical[privatecount[count, expr, counter][ id, privatestartStop[id, False] &], time]]; privatestartScheduledTask[ st : scheduledTaskObject[id_, expr_, {time_, count_}, start_, _]] := start - AbsoluteTime[] /. remaining_ :> With[{pst := privatestartScheduledTask[ scheduledTaskObject[ "", privatestartScheduledTask[ scheduledTaskObject[id, expr, {time, count}, Automatic, False]], {remaining, 1}, Automatic, False]]}, privateextraTasks[id] = Hold[pst]; pst] ClearAll[createScheduledTask, startScheduledTask, stopScheduledTask,$scheduledTask, removeScheduledTask,
$scheduledTask::usage = ""; scheduledTaskObject::usage = ""; SetAttributes[{createScheduledTask, runScheduledTask}, HoldFirst]; SetAttributes[scheduledTaskObject, HoldAll]; SetAttributes[{stopScheduledTask, removeScheduledTask}, Listable]; scheduledTasks[] = {}; privateidCounter = 0; privatestartStop[st : (sto : scheduledTaskObject)[__], b : True | False] := st /. sto[rest__, _] :> sto[rest, b]; privatestartStop[id_Integer, b : True | False] := scheduledTasks[] = scheduledTasks[] /. e : scheduledTaskObject[id, rest__] :> privatestartStop[e, b]; createScheduledTask[expr_, {time_, count_: 1}, start_: Automatic] := ++privateidCounter /. c_ :> scheduledTaskObject[c, expr, {time, count}, start, False] /. sto_ :> (AppendTo[scheduledTasks[], sto]; sto); createScheduledTask[expr_, time_: 1, rest___] := createScheduledTask[expr, {time, \[Infinity]}, rest]; startScheduledTask[ st : scheduledTaskObject[ id_, __]?privateSTQ] := (privatestartStop[id, True]; privatestartScheduledTask[st]; Null /; False) startScheduledTask[s_] := s; stopScheduledTask[ st : scheduledTaskObject[id_, expr_, {time_, count_}, __]?privateSTQ] := (Periodicals[] /. {HoldForm[ i : privatecount[sth__][id, __]] :> Quiet@RemovePeriodical[i]}; privateextraTasks[id] /. Hold[privatestartScheduledTask[ scheduledTaskObject[_, e_, ___]]] :> Quiet@RemovePeriodical[e]; Quiet[privateextraTasks[id] =.]; privatestartStop[id, False]; Null /; False) stopScheduledTask[st_] := st; runScheduledTask[stuff___] := startScheduledTask@createScheduledTask@stuff~privatestartStop~True; removeScheduledTask[ st : scheduledTaskObject[ id_, __]?privateSTQ] := (stopScheduledTask[st]; scheduledTasks[] = (DeleteCases[scheduledTasks[], scheduledTaskObject[id, __]]); st) removeScheduledTask[_] :=$Failed;


In case you are interested to copy or as reference, here go the usage messages

ToExpression[#, InputForm, Function[name, name::usage, HoldAll]] & /@
Names["System*Sche*"]


returns, copied as plain text

{CreateScheduledTask[expr] creates a task that will repeatedly evaluate expr once per second.
CreateScheduledTask[expr,time] creates a task that will repeatedly evaluate expr every time seconds.
CreateScheduledTask[expr,{time}] creates a task that will evaluate expr once after time seconds.
CreateScheduledTask[expr,{time,count}] creates a task that will try evaluating expr once every time seconds up to count times total.
CreateScheduledTask[expr,timespec,start] creates a task that will evaluate expr according to timespec starting at start time.,RemoveScheduledTask[obj] remove the obj from the list of currently set tasks.,ResetScheduledTask[obj] resets scheduled task object obj to the original parameter values.