DEV Community

Discussion on: Practical Functional Programming in JavaScript - Side Effects and Purity

Collapse
 
miketalbot profile image
Mike Talbot ⭐ • Edited

Inspired by this article, I fiddled around to enable a basic functional pipeline in js-coroutines so I could have a runner that started generator functions that yield to do a time check and enable its processing over multiple frames functionality. Wondering though if it would be better off making something for rubico that would do that same as my knowledge is definitely lacking in this area.

Collapse
 
richytong profile image
Richard Tong

I've mulled over supporting generator functions in rubico before, but couldn't find a great use case from my experience. I see your example with a generator function used with async functions here

      const process = pipe(
             parseAsync,
             function * (data) {
                let i = 0
                let output = []
                for(let item of data) {
                    output.push({...item, 
                       total: item.units * item.price,
                       score: complexScore(item)
                    })
                    if((i++ % 100)==0) yield
                }
                return output
             },
             tap(console.log),
             stringifyAsync
         )    

I see how this is useful, but I'm trying to think of all the use cases. The data and output make sense to me - data goes in and output goes out. I see yield in this case freeing up the event loop and splitting the processing up over multiple frames (assuming pipe is fully consuming the generated iterable then returning the output). Are there any other use cases for yield in the context of a generator function in pipe?

I'm a little hesitant to add in generator functions if this is the only use case (which I feel like it's not, I just need help with use cases) because I think I can achieve the same process splitting with async/await.

      const process = pipe(
             parseAsync,
             async function (data) {
                let i = 0
                let output = []
                for(let item of data) {
                    output.push({...item, 
                       total: item.units * item.price,
                       score: complexScore(item)
                    })
                    if((i++ % 100)==0) await Promise.resolve()
                }
                return output
             },
             tap(console.log),
             stringifyAsync
         ) 
Collapse
 
miketalbot profile image
Mike Talbot ⭐

The primary function of yield in js-coroutines is to test the amount of time remaining in the current idle part of a frame. You may also yield promises to await their completion.

js-coroutines is just basically providing a collaborative multi-tasking program runner. It does this by exposing everything it touches as an async function - so actually heavy lifting can be done in any pipe that can await async functions. That's enough