Erlang encourages poor Functional Design
srparish.wordpress.com
srparish.wordpress.com
The proposed refactor in the article doesn't look like idiomatic erlang to me. How would you refactor the code in the article?
I'd do something like this;
validate(_DbConn, {error, Reason}) ->
{error, Reason};
validate(DbConn, #req{body = ReqJsonStr}) ->
validate(DbConn, json:decode(ReqJsonStr));
validate(DbConn, {ok, #login_request{username = Username, password = Password}}) ->
validate(DbConn, {hash_password(Password), db:find_user(DbConn, Username)});
validate(_DbConn, {HashedPassword, {ok, #user_details{username = Username, hashed_password = HashedPassword}}}) ->
% Hashed password matches the found user record hashed password
% by the power of function pattern matching.
{ok, "hello " ++ Username};
validate(_DbConn, {_HashedPassword, _UserLookupResult}) ->
% Hashed password did not match or user not found.
{error, "wrong name or password"}.
Splitting into exported and "private" functions in module would leave a less messy api. This simply removes the case usage, coupling, highlights function pattern matching and makes for easily testable small functions.