Tell me more ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question

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,

Internal`AddPeriodical[Print["boo!"], 3]

Now you get a boo! every 3 seconds.

Internal`Periodicals[]

(* ==> {Print["boo!"]} *)

Now do

Internal`RemovePeriodical[Print["boo!"]]

to stop it.

Internal`Periodicals[]

(* ==> {} *)

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).

share|improve this answer
4  
Or, more annoyingly: Internal`AddPeriodical[Speak["boo!"], 3] but just be sure you're ready to invoke Internal`RemovePeriodical[Print["boo!"]] before going nuts! – murray Mar 11 '12 at 22:08
1  
@murray Nooo, you have to do Internal`RemovePeriodical[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[`private`count, HoldRest];
`private`count[_, expr_, count_Symbol][id_, ___] /; 
  Block[{$scheduledTask = `private`getST[id]}, expr; ++count]/;False := Null
e : `private`count[i_, _, count_Symbol][id_, endFun : _ : (Null &)] /;
   count === i := (Remove[count]; RemovePeriodical[e]; endFun[])
`private`count[___][___] := Null

`private`getST[id_] /; 
  MemberQ[scheduledTasks[], scheduledTaskObject[id, ___]] := 
 First@Cases[scheduledTasks[], scheduledTaskObject[id, ___]]
`private`getST[_] := $Failed;

`private`STQ[scheduledTaskObject[id_, expr_, time_, start_, _]] := 
 Length[Cases[scheduledTasks[]/. HoldPattern@\[Infinity] -> \[Infinity], 
    scheduledTaskObject[id, expr, time, start, _]/. HoldPattern@\[Infinity] -> \[Infinity]]] >= 1
`private`STQ[___] := False;

`private`startScheduledTask[
   st : scheduledTaskObject[id_, 
     expr_, {time_, count_}, (start_ /; start <= AbsoluteTime[]) | 
      Automatic, _]] := 
  Module[{counter = 0}, ClearAttributes[counter, Temporary];
   AddPeriodical[`private`count[count, expr, counter][
     id, `private`startStop[id, False] &], time]];

`private`startScheduledTask[
  st : scheduledTaskObject[id_, expr_, {time_, count_}, start_, _]] :=
  start - AbsoluteTime[] /. 
  remaining_ :> 
   With[{pst := `private`startScheduledTask[
       scheduledTaskObject[
        "", `private`startScheduledTask[
         scheduledTaskObject[id, expr, {time, count}, Automatic, 
          False]], {remaining, 1}, Automatic, 
        False]]}, `private`extraTasks[id] = Hold[pst]; pst]

ClearAll[createScheduledTask, startScheduledTask, 
  stopScheduledTask, $scheduledTask, removeScheduledTask, 
      scheduledTasks, scheduledTaskObject, runScheduledTask];
    $scheduledTask::usage = ""; scheduledTaskObject::usage = "";
SetAttributes[{createScheduledTask, runScheduledTask}, HoldFirst];
SetAttributes[scheduledTaskObject, HoldAll];
SetAttributes[{stopScheduledTask, removeScheduledTask}, Listable];


scheduledTasks[] = {}; `private`idCounter = 0;
`private`startStop[st : (sto : scheduledTaskObject)[__], 
   b : True | False] := st /. sto[rest__, _] :> sto[rest, b];
`private`startStop[id_Integer, b : True | False] := 
  scheduledTasks[] = 
   scheduledTasks[] /. 
    e : scheduledTaskObject[id, rest__] :> `private`startStop[e, b];

createScheduledTask[expr_, {time_, count_: 1}, 
   start_: Automatic] := ++`private`idCounter /. 
    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_, __]?`private`STQ] := (`private`startStop[id, 
   True]; `private`startScheduledTask[st]; Null /; False)
startScheduledTask[s_] := s;

stopScheduledTask[
  st : scheduledTaskObject[id_, 
     expr_, {time_, 
      count_}, __]?`private`STQ] := (Periodicals[] /. {HoldForm[
      i : `private`count[sth__][id, __]] :> 
     Quiet@RemovePeriodical[i]}; `private`extraTasks[id] /. 
   Hold[`private`startScheduledTask[
      scheduledTaskObject[_, e_, ___]]] :> Quiet@RemovePeriodical[e];
  Quiet[`private`extraTasks[id] =.];
  `private`startStop[id, False]; Null /; False)

stopScheduledTask[st_] := st;

runScheduledTask[stuff___] := 
  startScheduledTask@createScheduledTask@stuff~`private`startStop~True;

removeScheduledTask[
  st : scheduledTaskObject[
     id_, __]?`private`STQ] := (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.
ResetScheduledTask[obj,timespec]  resets scheduled task timing to timespec.
ResetScheduledTask[obj,timespec,offset] resets scheduled task time offset to offset.,RunScheduledTask[expr] schedules and starts a task that will repeatedly evaluate expr once per second.
RunScheduledTask[expr,time] schedules and starts a task that will repeatedly evaluate expr every time seconds.
RunScheduledTask[expr,{time}] schedules and starts a task that will evaluate expr once after time seconds.
RunScheduledTask[expr,{time,count}] schedules and starts a task that will try evaluating expr once every time seconds up to count times.
RunScheduledTask[expr,timespec,start] schedules a task that will automatically start at start time.,ScheduledTaskObject[id,expr,spec,...]  is a task object specifying future evaluation of expr according to spec.,ScheduledTasks[]  returns a list of ScheduledTaskObject expressions that represent current tasks.,StartScheduledTask[obj] starts the task represented by obj.,StopScheduledTask[obj] deactivates the task obj.,$ScheduledTask returns the current ScheduledTaskObject. }
share|improve this answer
Please still test it. I just made the code of yesterday a little bit neater – Rojo Jul 15 '12 at 16:51
I really wanted your work to pay off but unfortunately I still got a crash. :-/ I shall try to find a way to repay your efforts on this. – Mr.Wizard Aug 11 '12 at 14:22
@Mr.Wizard forget about it. But you could give the question I just posted a shot ;D – Rojo Aug 11 '12 at 14:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.