Reactive Scratch tutorial

Time

A Reactive Scratch program describes how to react to events at each reaction instant. A reaction instant happens instataneously at some point in real time, as in the following figure, where the arrowed line represents real time, and the ticks represent the reaction instants:

reaction instants

In Scratch, reaction instants are every thirtieth (1/30) of a second.

Control

How to react at a given instant is described

  1. at the first reaction instant, by the part of the program in between the start reacting when flag clicked and the next pause
  2. otherwise, by the part of the program in between the current pause block and the next, in program order.

The program below runs for one reaction instant, and at that reaction instant, does nothing.

start reacting when flag clicked
pause

The program below runs forever, and at each reaction instant, does nothing.

start reacting when flag clicked
loop
pause

⚠️ Every loop needs a pause inside of it - so that we are sure that we never have to execute an infinite number of instructions in a finite time. If the program does not have enough pauses, Reactive Scratch inserts some with a very simple heuristic, which may not match what you want.

A more interesting program is one that does something that the user can see, for example emits a signal to turn right by 15 degrees at each reaction instant, forever:

start reacting when flag clicked
loop
	turn (Cat v) cw (15) degrees
	pause
end

The program above turns the Cat sprite at each reaction instant, but this does not mean that it turns it at regular time intervals in real time.

Concurrency

Programs can be combined concurrently, so that they execute together. We avoid saying "at the same time" to not confuse this with real, physical time.

At each reaction instant, the program below turns the Cat sprite by 15 degrees, and moves the Mouse sprite by 10 steps.

start reacting when flag clicked
loop
	concurrently
		turn (Cat v) cw (15) degrees
		pause
	with
		move (Mouse v) (10) steps
		pause
	end
end

The following program turns the Cat sprite at every reaction instant (and moves the Mouse sprite every two reaction instants):

start reacting when flag clicked
concurrently
	loop
		turn (Cat v) cw (15) degrees
		pause
	end
with
	loop
		move (Mouse v) (10) steps
		pause
		pause
	end
end

...whereas the following program turns the Cat sprite every two reaction instants:

start reacting when flag clicked
loop
	concurrently
		turn (Cat v) cw (15) degrees
		pause
	with
		move (Mouse v) (10) steps
		pause
		pause
	end
end

...and so does this one:

start reacting when flag clicked
loop
	concurrently
		turn (Cat v) cw (15) degrees
	with
		move (Mouse v) (10) steps
		pause
		pause
	end
end

Signals

Different parts of the program can communicate to work together using signals. A signal is declared with a signal [S] in block. The parts of the program inside that block can then emit that signal with emit [S], and test for its presence with signal [S] is present.

The program below has one part that emits a signal S, and another that, concurrently with it, has the Mouse sprite say "Squeak" when that signal S is present.

start reacting when flag clicked
signal [S] in
	loop
		concurrently
			emit [S]
		with
			if <signal [S] is present> then
				have (Mouse v) say [Squeak]
			else
			end
		end
		pause
	end
end

Testing on signals can be combined using the usual boolean operators:

if <<signal [S] is present> and <not <signal [S2] is present>>> then
	show (Cat v)
else
	hide (Apple v)
end

Sensing

Sensing is done by testing for signals. A sensing signal is declared and emitted outside the program.

start reacting when flag clicked
loop
if <(Cat v) touching (Mouse v)?> then
	hide (Mouse v)
else
end
end

Acting

Acting is done by emitting signals (TODO: not quite yet). An acting signal is declared and tested outside of the program.

start reacting when flag clicked
turn (Cat v) cw (15) degrees
show (Cat v)

Real time

Real time is also a special case of signals.

Preemption

Traps

A part of the program can be terminated early by exiting to a trap. A trap is declared with a trap [T] in block. The part of the program inside the declaration of a trap T can be exited early with exit [T].

start reacting when flag clicked
trap [T] in
	loop
		if <key (space v) pressed?> then
			exit [T]
		else
			turn (Cat v) cw (15) degrees
		end
		pause
	end
end
have (Mouse v) say [Squeak]

Traps can be nested:

start reacting when flag clicked
loop
	trap [T] in
		loop
			trap [U] in
				loop
					if <key (space v) pressed?> then
						exit [U]
					else
						if <key (x v) pressed?> then
							exit [T]
						else
							turn (Cat v) cw (15) degrees
						end
					end
					pause
				end
			end
			have (Cat v) say [Meow]
			pause
		end
	end
	have (Mouse v) say [Squeak]
	pause
end

To make a part of the program make another, concurrent part of the program terminate early by exiting to a trap, the first part can emit a signal, and the second part can be composed concurrently with a test of that signal that causes an exit to the trap:

start reacting when flag clicked
signal [S] in
	concurrently
		...
		emit [S]
		...
	with
		trap [T] in
			concurrently
				...
			with
				if <signal [S] is present?> then
					exit (T)
				else
				end
			end
		end
  	end
end

This is sufficiently common that there is a block for that: abort

start reacting when flag clicked
signal [S] in
	concurrently
		...
		emit [S]
		...
	with
		abort
			...
		end
		when <signal [S] is present?>
	end
end

Suspension

A part of the program can be suspended when a signal is present with suspend.

start reacting when flag clicked
suspend
	loop
		turn (Cat v) cw (15) degrees
		pause
	end
end
when <key [space v] pressed>

Variables

TODO

Valued signals and traps

TODO


Reactive Scratch is developed by Jean Pichon-Pharabod.

Last modified: 2019/07/13