implement generic two-sided binary op