Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A Brief Introduction to Dialyzer and Proper

A Brief Introduction to Dialyzer and Proper

Christopher Meiklejohn

February 02, 2014
Tweet

More Decks by Christopher Meiklejohn

Other Decks in Programming

Transcript

  1. -opaque gcounter() :: orddict:orddict(). ! -type gcounter_op() :: increment |

    {increment, pos_integer()}. ! %% @doc Create a new, empty `gcounter()' -spec new() -> gcounter(). new() -> orddict:new(). ! %% @doc Create a `gcounter()' with an initial update -spec new(term(), pos_integer()) -> gcounter(). new(Id, Count) when is_integer(Count), Count > 0 -> {ok, Cnt} = update({increment, Count}, Id, new()), Cnt.
  2. %% @doc Create a `gcounter()' with an initial update -spec

    new(term(), atom()) -> gcounter(). new(Id, Count) when is_integer(Count), Count > 0 -> {ok, Cnt} = update({increment, Count}, Id, new()), Cnt.
  3. %% @doc Create a `gcounter()' with an initial update -spec

    new(riak_dt:actor(), pos_integer()) -> gcounter(). new(Id, Count) when is_integer(Count), Count > 0 -> {ok, Cnt} = update({increment, Count}, Id, new()), Cnt. ! %% @doc `increment' the entry in `GCnt' for `Actor' by 1 or `{increment, Amt}'. %% returns an updated `gcounter()' or error if `Amt' is not a `pos_integer()' -spec update(gcounter_op(), riak_dt:actor(), gcounter()) -> {ok, gcounter()}. update(increment, Actor, GCnt) -> {ok, increment_by(1, Actor, GCnt)}; update({increment, Amount}, Actor, GCnt) when is_integer(Amount), Amount > 0 -> {ok, increment_by(Amount, Actor, GCnt)}.
  4. riak_dt_gcounter.erl:64: Function new/2 has no local return riak_dt_gcounter.erl:65: The call

    riak_dt_gcounter:update({'incremet',pos_integer()},Id::any(),riak_dt_g counter:gcounter()) breaks the contract (gcounter_op(),riak_dt:actor(),gcounter()) -> {‘ok',gcounter()}
  5. %% @doc Create a `gcounter()' with an initial update -spec

    new(riak_dt:actor(), pos_integer()) -> gcounter(). new(Id, Count) when is_integer(Count), Count > 0 -> {ok, Cnt} = update({increment, Count}, Id, new()), Cnt. ! %% @doc `increment' the entry in `GCnt' for `Actor' by 1 or `{increment, Amt}'. %% returns an updated `gcounter()' or error if `Amt' is not a `pos_integer()' -spec update(gcounter_op(), riak_dt:actor(), gcounter()) -> {ok, gcounter()}. update(increment, Actor, GCnt) -> {ok, increment_by(1, Actor, GCnt)}.
  6. -module(simple_props). ! %% Properties are automatically exported. -include_lib("proper/include/proper.hrl"). ! %%

    Functions that start with prop_ are considered properties prop_t2b_b2t() -> ?FORALL(T, term(), T =:= binary_to_term(term_to_binary(T))).
  7. -spec new() -> stack(_T). new() -> {0, []}. ! -spec

    push(T, stack(T)) -> stack(T). push(X, {N,Elems}) -> {N+1, [X|Elems]}. ! -spec pop(stack(T)) -> {T,stack(T)}. pop({0, []}) -> throw(stack_empty); pop({N, [Top|Rest]}) when N > 0 -> {Top, {N-1,Rest}}.
  8. prop_delete() -> ?FORALL(L, non_empty(list(integer())), ?FORALL(X, elements(L), lists:foldl(fun(Y, Acc) -> case

    Y of X -> Acc + 1; _ -> Acc end end, 0, L) - 1 == lists:foldl(fun(Y, Acc) -> case Y of X -> Acc + 1; _ -> Acc end end, 0, lists:delete(X, L)))).