Yet another time it comes up. But now, after functional programming being commonplace, we at least know the answer to the "why" question. Consider the "classical OOP" method signature: email.send() vs "the anemic way" emailSender.send(message: Email) If there is only one way to send email (SMTP), things works fine. But let's assume we have to implement another way (e.g. Mailgun API). In the "anemic" case everything i…
> Which changes Email::send signature, which leads to breaking API changes and extensive manual refactoring of the entire codebase. Only if you decide to change the signature, there are other ways to achieve the same result.
(let ((*emailer* mailgun-client))
(send email))
Or, using Go contexts (which are just a way of hacking in dynamic variables): ctx = email.NewContext(ctx, mailgunClient)
email.Send(ctx)
And in email.Send: emailer, ok := EmailerFromContext(ctx)
if !ok {
emailer = defaultSMTPEmailer
}