Qu

Language & UI

Reactive watch

all three `watch` trigger forms (`watch file(path)`, `watch <variable>`, `watch url(...)`), each firing exactly once on a genuine change and staying silent on an unchanged `pump_watches()` call.

catalog/qu_watch_reactive.qu

`watch` never runs "in the background" -- Qu's interpreter is single- threaded with no event loop. `watch ... end` only registers a callback and records a baseline (a file's mtime, a variable's current value, or one real HTTP fetch); the body only ever runs when the script explicitly calls `pump_watches()`, which checks every registered watch's REAL current state exactly once. This script drives that loop by hand, exactly mirroring the mechanics of `watch_file_fires_once_on_a_real_ mtime_change_and_not_on_an_unchanged_pump` and `watch_var_fires_on_a_ genuine_value_change_and_not_on_a_same_value_reassignment` in `engine/crates/qu-interp/src/lib.rs`. `watch url(...)` needs a live server to show a genuine body change against, which this standalone demo doesn't stand up -- it's registered and pumped for real (proving registration + one real fetch actually work against a real, reachable URL) but is not exercised for the "fires on change" case the way the file/variable watches are.

What it exercises

How it works

where nothing changed.

file_fires = 0
watch file(watch_target) do
    file_fires = file_fires + 1
end

f1 = pump_watches()
print("pump #1 (nothing touched yet): fired={f1}, file_fires={file_fires}")

touch(watch_target)
f2 = pump_watches()
print("pump #2 (just touched the file): fired={f2}, file_fires={file_fires}")

f3 = pump_watches()
print("pump #3 (no change since pump #2): fired={f3}, file_fires={file_fires}")

same-value reassignment.

threshold = 10
var_fires = 0
watch threshold do
    var_fires = var_fires + 1
end

g1 = pump_watches()
print("pump #4 (threshold unchanged): fired={g1}, var_fires={var_fires}")

threshold = 25
g2 = pump_watches()
print("pump #5 (threshold changed to {threshold}): fired={g2}, var_fires={var_fires}")

threshold = 25
g3 = pump_watches()
print("pump #6 (reassigned the SAME value, 25): fired={g3}, var_fires={var_fires}")

server).

url_fires = 0
watch url("https://example.com/", interval_seconds=3600) do
    url_fires = url_fires + 1
end
h1 = pump_watches()
print("pump #7 (url watch just registered, interval not elapsed yet): fired={h1}, url_fires={url_fires}")

Summary

print("")
print("Total file watch fires: {file_fires} (expected 1)")
print("Total variable watch fires: {var_fires} (expected 1)")
print("Total url watch fires this run: {url_fires} (expected 0 -- baseline fetch only)")

# Clean up the demo file this script created.

Results

printed
pump #1 (nothing touched yet): fired=0, file_fires=0
pump #2 (just touched the file): fired=1, file_fires=1
pump #3 (no change since pump #2): fired=0, file_fires=1
pump #4 (threshold unchanged): fired=0, var_fires=0
pump #5 (threshold changed to 25): fired=1, var_fires=1
pump #6 (reassigned the SAME value, 25): fired=0, var_fires=1
pump #7 (url watch just registered, interval not elapsed yet): fired=0, url_fires=0

Total file watch fires: 1 (expected 1)
Total variable watch fires: 1 (expected 1)
Total url watch fires this run: 0 (expected 0 -- baseline fetch only)

The whole program

Runnable as it stands: qu run catalog/qu_watch_reactive.qu

# qu_watch_reactive.qu -- all three `watch` trigger forms (`watch

# file(path)`, `watch <variable>`, `watch url(...)`), each firing exactly

# once on a genuine change and staying silent on an unchanged

# `pump_watches()` call.

#

# `watch` never runs "in the background" -- Qu's interpreter is single-

# threaded with no event loop. `watch ... end` only registers a callback

# and records a baseline (a file's mtime, a variable's current value, or

# one real HTTP fetch); the body only ever runs when the script explicitly

# calls `pump_watches()`, which checks every registered watch's REAL

# current state exactly once. This script drives that loop by hand,

# exactly mirroring the mechanics of `watch_file_fires_once_on_a_real_

# mtime_change_and_not_on_an_unchanged_pump` and `watch_var_fires_on_a_

# genuine_value_change_and_not_on_a_same_value_reassignment` in

# `engine/crates/qu-interp/src/lib.rs`. `watch url(...)` needs a live

# server to show a genuine body change against, which this standalone demo

# doesn't stand up -- it's registered and pumped for real (proving

# registration + one real fetch actually work against a real, reachable

# URL) but is not exercised for the "fires on change" case the way the

# file/variable watches are.

#

# Constructs exercised (all real, verified-working builtins):

#   watch file(path) do ... end

#   watch <variable name> do ... end

#   watch url(url, [interval_seconds=]) do ... end

#   pump_watches()

#   touch(path)                    -- real mtime bump used to trigger the file watch


backend auto

watch_target = "qu_watch_reactive_demo.txt"
# Start from a clean slate so this script is repeatable run after run.

if file_exists(watch_target)
    f = fopen(watch_target, "w")
    write_line(f, "reset")
    close(f)
end if

#%% Form 1: watch file(path) -- fires on a real mtime change, not on a pump

#%% where nothing changed.

file_fires = 0
watch file(watch_target) do
    file_fires = file_fires + 1
end

f1 = pump_watches()
print("pump #1 (nothing touched yet): fired={f1}, file_fires={file_fires}")

touch(watch_target)
f2 = pump_watches()
print("pump #2 (just touched the file): fired={f2}, file_fires={file_fires}")

f3 = pump_watches()
print("pump #3 (no change since pump #2): fired={f3}, file_fires={file_fires}")

#%% Form 2: watch <variable> -- fires on a genuine value change, not on a

#%% same-value reassignment.

threshold = 10
var_fires = 0
watch threshold do
    var_fires = var_fires + 1
end

g1 = pump_watches()
print("pump #4 (threshold unchanged): fired={g1}, var_fires={var_fires}")

threshold = 25
g2 = pump_watches()
print("pump #5 (threshold changed to {threshold}): fired={g2}, var_fires={var_fires}")

threshold = 25
g3 = pump_watches()
print("pump #6 (reassigned the SAME value, 25): fired={g3}, var_fires={var_fires}")

#%% Form 3: watch url(...) -- registers + performs one real baseline fetch

#%% against a real, reachable URL; not exercised for a body-change fire in

#%% this standalone demo (that needs a live server whose response actually

#%% changes between two fetches -- see lib.rs's own

#%% `watch_url_fires_on_a_real_body_change_over_loopback_and_not_on_an_

#%% unchanged_poll` test for that scenario against a controlled local

#%% server).

url_fires = 0
watch url("https://example.com/", interval_seconds=3600) do
    url_fires = url_fires + 1
end
h1 = pump_watches()
print("pump #7 (url watch just registered, interval not elapsed yet): fired={h1}, url_fires={url_fires}")

#%% Summary

print("")
print("Total file watch fires: {file_fires} (expected 1)")
print("Total variable watch fires: {var_fires} (expected 1)")
print("Total url watch fires this run: {url_fires} (expected 0 -- baseline fetch only)")

# Clean up the demo file this script created.