implement defonce macro