Imho types should make the programmer live easier, not more difficult.
Looking at the first code, and at the second peace of code. Imho the second piece of code is easier to read, but it does lack validation logic & testing.
First of all, from a type-theory point of view, both Email and WebForm have the same type. (same signature).
Also from a theoretical point of view, i think a type should not have an instance if its not valid and "EmailAddress" of value "aasda" should not exists. However it is allowed in his types.
Also, I don't see how defining lots of very specific types such as FromAddress and ToAddress are really making live easier.
Something like this does the job, and is typesafe (in golang):
type EmailAddress string
type Email struct {
to EmailAddress
from EmailAddress
subject string
body string
}
func sendEmail(webForm string) err = {
email, err := validateEmailForm(form) # performs validation
if err {
return err
}
err := email_service.sendEmail(email)
if err {
return err
}
}
Tests will simply use the returnValue of sendMail to validate its inner working.
First of all, from a type-theory point of view, both Email and WebForm have the same type. (same signature).
Also from a theoretical point of view, i think a type should not have an instance if its not valid and "EmailAddress" of value "aasda" should not exists. However it is allowed in his types.
Also, I don't see how defining lots of very specific types such as FromAddress and ToAddress are really making live easier.
Something like this does the job, and is typesafe (in golang):
Tests will simply use the returnValue of sendMail to validate its inner working.