Open freeformflow opened 9 years ago
The trick here is that times
should be lean and mean because the intent is to use it with benchmark
. So I don't want too much overhead.
We could check for a promise-reponses and then loop using a wrapper function. Ex:
times = (f, n) ->
m = 0
_f = ->
if m++ < n
if (isPromise (p = do f)) then p.then _f else do _f
# synchronous use
times foo, 1e3
# asynchronous use
(times foo, 1e3).then ...
Right now, times
returns an array of each iteration's result. I'd like to retain that property. Would the following be acceptable?
times = (f, n) ->
m = 0
results = []
do _f = ->
if m++ < n
if (isPromise (p = do f))
p.then (r) ->
results.push r
do _f
else
results.push p
do _f
else
results
# synchronous use
bar = times foo, 1e3
assert isArray(bar) == true
# asynchronous use
call ->
bar = yield times foo, 1e3
assert isArray(bar) == true
Hm. I think actually we should get rid of this property, since that could consume a great deal of memory unexpectedly. And also ruins the main use case, which is use with benchmark
.
OTOH, I can also see the use case you're focused on. I think there might be two functions here. One which converts a function into a producer that executes N times. Technically, this is already possible:
takeN 1e3, iterator f
or (asynchronous case):
takeN 1e3, reactor f
but perhaps this should be a dedicated function? The trick would be determining dynamically whether the function is async or not. I've thought about this a great deal and generally decided to avoid this kind of thing in favor of explicit declaration (as above).
times
is currently just an until-loop that returns an array containing the result of every iteration. I propose adding support for asynchronous functions, but I'm not sure what the best policy would be.