add a generic factorial implementation