abstracted out the main loop in a perhaps too javascript-y way