REBOL doesn't have conventional multi-tasking/threading support. However, you can fake it using the GUI in REBOL/View, which since you're using the sound stuff, I assume you're using.
The key is to set a timer on one of your interface objects that periodically calls a function to check on the status of the things you want to monitor. In this example, I've rewritten your alarm function to set the alarm-data variable, which will be checked by the periodic function when it gets called every second from the monitor object in the layout (that's what the "rate 1 feel [engage: :periodic]" stuff does).
While crude, this trick goes a long way to compensate for missing threads (if you can put up with having a GUI). You can check/update all sorts of things in the periodic function, even implement simple multi-tasking with a state machine. Also note that you could set up alarm-data as a list of alarms instead of a single one if you need more than one.
Also see http://www.rebol.com/docs/view-face-events.html for more information about special event handling.
REBOL [
Title: "Alarmer"
File: %alarm.r
Author: oofoe
Date: 2010-04-28
Purpose: "Demonstrate non-blocking alarm."
]
alarm-data: none
alarm: func [
"Set alarm for future time."
seconds "Seconds from now to ring alarm."
message [string! unset!] "Message to print on alarm."
] [
alarm-data: reduce [now/time + seconds message]
]
ring: func [
"Action for when alarm comes due."
message [string! unset!]
] [
set-face monitor either message [message]["RIIIING!"]
; Your sound playing can also go here (my computer doesn't have speakers).
]
periodic: func [
"Called every second, checks alarms."
fact action event
] [
if alarm-data [
; Update alarm countdown.
set-face monitor rejoin [
"Alarm will ring in "
to integer! alarm-data/1 - now/time
" seconds."
]
; Check alarm.
if now/time > alarm-data/1 [
ring alarm-data/2
alarm-data: none ; Reset once fired.
]
]
]
view layout [
monitor: text 256 "Alarm messages will be shown here."
rate 1 feel [engage: :periodic]
button 256 "re/start countdown" [
alarm 10 "This is the alarm message."
set-face monitor "Alarm set."
]
]