For instance, array.map accepts a callback that returns a value.

const newArray = oldArray.map(item => doSomethingTo(item));

Promises also accept callbacks that return a value.

const requestPromise = $.ajax(...).then(res => doSomethingTo(res));

But the way I see most event emitters, they seem non-functional by design.

const emitter = new EventEmitter();

// emitter.on mutates the emitter to register event
// returns nothing in most cases.

emitter.on('SOME_EVENT', event => {

  // Do something entirely irrelevant to the emitter.
  // Do something that mutates something outside the callback.
  // Returns nothing unlike array.map and promise callbacks.
  // Return value is irrelevant to the caller.


// Executes callbacks but return values are irrelevant.
// Returns nothing.


So if my understanding of functional programming is correct, event emitter callbacks aren't pure nor transparent if this is the case.

Can event emitters be written in a more functional way? Or is this a limitation of the mechanism? Are event-driven and functional incompatible? How are event emitters done in other, more functional languages?

  • 2
    If the event emitter's type is Event -> GlobalState -> GlobalState (or equivalent) then sure. Commented Sep 22, 2016 at 2:41
  • Observable values can be used in a monadic way.
    – Basilevs
    Commented Jan 20, 2017 at 19:52

1 Answer 1


In the Redux world (which took it from the functional programming world), it works like this:

function reducer(state, action) {
   // action is the "event"
   switch (action.type) {
       case 'SOME_EVENT':
           return {...state, value: 'modified'}
           return state;

This allows your event handling to be pure. All your function does it take the current state and the event, and return a new event.

  • 2
    Redux was what I had in mind with this question. The reducer part is ok, take old state, construct new state. The part where I'm curious is the dispatch and registration phase, which are essentially like event emitters. Wondering how that part could be functional.
    – Joseph
    Commented Sep 22, 2016 at 12:57
  • 2
    @JosephtheDreamer, what about passing every single event to your reducer? There is no need to register, you simply ignore events you don't care about. There is no need to dispatch because you are already in the reducer. Commented Sep 22, 2016 at 17:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.