pandastrike / panda-parchment

JavaScript helpers for use in functional programming.
MIT License
1 stars 3 forks source link

Determine How "times()" Should Handle Asynchronous Functions #9

Open freeformflow opened 9 years ago

freeformflow commented 9 years ago

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.

dyoder commented 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 ...
freeformflow commented 9 years ago

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
dyoder commented 9 years ago

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).