[erlang-questions] Temporarily violating record type constraints annoys dialyzer

Roger Lipscombe roger@REDACTED
Mon Nov 12 12:35:02 CET 2018


On 12 November 2018 at 11:11, Brujo Benavides <elbrujohalcon@REDACTED> wrote:
> Hi Roger,
>
> According to how you use your record, its spec should actually be…
>
> -record widget {
>    id :: undefined | binary(),
>    name :: undefined | binary(),
>    size :: undefined | integer()
> }.
>
> That will silence dialyzer or, putting it in the right perspective: That
> will be a spec that matches how your code actually treats that record.
> And that’s because: What happens if Props doesn’t have a tuple for name?

I figured someone would say that. The answer is that Props *always*
has a tuple for name -- it was written to a data store with that
invariant. But I can see that it's hard to tell dialyzer this.

> If not having a {name, Name} tuple in Props is an invalid scenario, you
> should raise some sort of error.
> In that case I would recommend you to keep the record definition as-is, but
> fill the whole record at once:
>
> parse_widget(Props) ->
>   #widget{
>     id = get_value(id, Props),
>     name = get_value(name, Props),
>>   }.
>
> get_value(Key, Props) ->
>   {Key, Value} = lists:keyfind(Key, 1, Props),
>   Value.

I was kinda hoping to avoid that -- I've got a vague feeling that we
did this for performance reasons. Of course, those assumptions are
probably no longer valid and need re-checking.

> Hope this helps :)

Only in the "you're doing it wrong" sense :)



More information about the erlang-questions mailing list