3.1 Binding arguments to a handler
See http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/tutorial/tuttimer3.html
In Felix, this is a no-brainer, we just use currying. Just add the extra argument prior to the last one. First our baseline wait routine:
include "std/io/faio"; proc wait_until ( clock:Faio::alarm_clock_t, delta:double, p:Faio::alarm_clock_t->0) { Faio::sleep (clock, delta); p clock; }
Now our client routine has "two arguments" instead of one.
proc p (pcount:&int) (clock:Faio::alarm_clock_t) { if *pcount < 5 do println$ *pcount; pcount <- *pcount + 1; wait_until (clock, 1.0 , p pcount); done }
A little more explanation is useful. The type of the routine above is:
&int -> Faio::alarm_clock -> 0
Because {->} is right associative, this actually means:
&int -> (Faio::alarm_clock -> 0)
This means p
is not actually a procedure! Rather it is a function
which accepts a pointer to an int
, and returns a
procedure. (Well technically .. a procedure closure).
So here is our invocation:
var count = 0; var clock = #Faio::mk_alarm_clock; wait_until (clock, 1.0, p &count); println$ "Final count is " + (str count);
Note that the argument {p &count} is a procedure closure. We have
applied the function p
to the pointer to int
value {&count}
and got back the closure of a procedure accepting the next argument,
a clock, which has the type required by wait_until
.
Test with
build/release/host/bin/flx --test=build/release src/web/tut/async_03.html