On 09/12/2014 03:45 AM, Hans Bolinder wrote:
Hi,
I've been pondering your idea for a while now, thinking along the
lines that it should be possible to do without adding any special
syntax. It might be possible to use -Wunderspecs (or even the not
recommended -Wspecdiffs), but there seem to be several things that
would need to be modified in the dialyzer_contracts module, though.
I'll try to find some time to look into the details.
BTW, it would be interesting to see how you've implemented the check.
I couldn't find any examples (looked for nowarn_unused_function), but
I only downloaded CloudI.
I haven't used nowarn_unused_function to provide a type assertion within the CloudI source code. A module which I would want a type assertion in (once the httpc:method() type exists, I had thought it already exists) is https://github.com/CloudI/CloudI/blob/develop/src/lib/cloudi_service_http_client/src/cloudi_service_http_client.erl#L520-L535 . You can see from the module that there is an implicit assumption that "method() :: head | get | put | post | trace | options | delete" which is valid based on the current inets documentation at http://www.erlang.org/doc/man/httpc.html . A concrete example for what I had meant by "a dirty trick" is the test module at the end of the email. That approach required using -Wspecdiffs which generates a lot of noise that isn't helpful (and isn't recommended as you mentioned). So a -type_assert could make this much clearer and the developer could see a basic type assertion fail to understand that assumptions within a module are no longer
true, making it easier to update the source code.
I started thinking about this problem when using the riak erlang client source
code which caused me to create the code below:
-include_lib("riakc/include/riakc.hrl").
-type index_results_check() :: {index_results_v1,
[binary()] | 'undefined',
[{integer() | binary(),
binary()}] | 'undefined',
'undefined' | binary()}.
-export_type([index_results/0]).
% code that uses index_results_check() instead of index_results() is below
That approach can provide something similar, but depends on a local type being
hard-coded, replicating an external module's type. That doesn't necessarily
work in the cloudi_service_http_client.erl file but may be made to work by
adding more functions (unnecessary complication). So the suggestion to add
-type_assert was just due to not seeing a better path to making sure dialyzer
would break. I haven't attempted to implement changes to support -type_assert
syntax and I am not sure about the changes required. I can help with the
changes, but I thought it was important to make sure the addition is agreeable
before changes are created.
Thanks,
Michael
Best regards,
Hans Bolinder, Erlang/OTP team, Ericsson
% run with:
% erlc +debug_info test.erl
% dialyzer -Wspecdiffs test.beam
-module(test).
-export([test/0]).
test() ->
ok.
% would normally be an external module's type to assert on,
% making sure that dialyzer will complain if the type changes
%-type method() :: head | get | put | post | trace | options | delete.
-type method() :: head | get | put | post | trace | options | delete | string().
-compile({nowarn_unused_function,
[{httpc_method_assert, 1},
{httpc_method_check, 1}]}).
-spec httpc_method_assert(head | get | put | post | trace | options | delete) ->
ok.
httpc_method_assert(T) ->
ok = httpc_method_check(T).
-spec httpc_method_check(method()) ->
ok.
httpc_method_check(_) ->
ok.
_______________________________________________
eeps mailing list
[email protected]
http://erlang.org/mailman/listinfo/eeps