[erlang-questions] FW: Any wisdom to offer on "tagged return values"
Bryan Fink
bryan.fink@REDACTED
Thu May 7 16:34:44 CEST 2009
On Wed, May 6, 2009 at 1:24 PM, David Mercer <dmercer@REDACTED> wrote:
> You could always extract the element you want of a tuple using element/2
> thus allowing chaining. E.g.:
>
> element(2, {ok,_} = dict:find(...))
Having used this approach myself before, I couldn't resist enumerating
its alternatives (except for parse transform :P):
-module(tagged_tuples).
-export([ex1/0, ex2/0, ex3/0, ex4/0, ex5/0, ex6/0]).
ex1() ->
{ok, This} = get_this(),
{ok, That} = get_that(This),
{ok, Next} = get_next(That),
Next.
ex2() ->
element(2, {ok, _}=get_next(element(2, {ok, _}=get_that(element(2,
{ok, _}=get_this()))))).
-define(OK(Expr), element(2, {ok, _}=Expr)).
ex3() ->
?OK(get_next(?OK(get_that(?OK(get_this()))))).
-define(UW(Match, Expr), element(2, {Match, _}=Expr)).
ex4() ->
?UW(ok, get_next(?UW(ok, get_that(?UW(ok, get_this()))))).
ok({ok, Val}) -> Val.
ex5() ->
ok(get_next(ok(get_that(ok(get_this()))))).
uw(Match, {Match, Val}) -> Val.
ex6() ->
uw(ok, get_next(uw(ok, get_that(uw(ok, get_this()))))).
get_this() -> {ok, this}.
get_that(this) -> {ok, that}.
get_next(that) -> {ok, next}.
As written, ex1-6/0 will each return the atom 'next':
> tagged_tuples:ex1().
next
> tagged_tuples:ex2().
next
> tagged_tuples:ex3().
next
> tagged_tuples:ex4().
next
> tagged_tuples:ex5().
next
> tagged_tuples:ex6().
next
Change any of the 'ok' atoms in get_*, though, and you'll get various
kinds of errors:
> tagged_tuples:ex1().
** exception error: no match of right hand side value {bork,this}
in function tagged_tuples:ex1/0
> tagged_tuples:ex2().
** exception error: no match of right hand side value {bork,this}
in function tagged_tuples:ex2/0
> tagged_tuples:ex3().
** exception error: no match of right hand side value {bork,this}
in function tagged_tuples:ex3/0
> tagged_tuples:ex4().
** exception error: no match of right hand side value {bork,this}
in function tagged_tuples:ex4/0
> tagged_tuples:ex5().
** exception error: no function clause matching tagged_tuples:ok({bork,this})
in function tagged_tuples:ex5/0
> tagged_tuples:ex6().
** exception error: no function clause matching tagged_tuples:uw(ok,{bork,this})
in function tagged_tuples:ex6/0
Completely dodging the question of whether you *should*, it's good to
have a few strategies to work with code that *does*. (Also dodging
the question of which alternative is "best", "nicest", etc.)
-Bryan
More information about the erlang-questions
mailing list