[erlang-questions] Record-like syntax for dictionaries

Anton Lavrik <>
Wed Jan 5 17:18:53 CET 2011


On Wed, Jan 5, 2011 at 8:56 AM, Andy Kriger <> wrote:
> That looks great. Is there a way that fetching a non-existent field can
> return undefined instead of requiring a catch?

No, but it is easy to add support for such behavior. However, I
wouldn't make it the default and I'm not sure what would be the best
way to specify which of the two behaviors you want.

In general, I'm reluctant to introducing complicated features that are
based on parse transformations. This is why, for instance, it is
allowed to define -dict_alais() only once per module. Adding
configurable behavior would make things less explicit -- looking at
the code you wouldn't be able to tell which behavior is applied
without looking at the configuration.

Anton

>
> On Wed, Jan 5, 2011 at 4:30 AM, Anton Lavrik <> wrote:
>
>> Hi all,
>>
>> While playing with Erlang parse transformations, I came up with the
>> idea of using a record-like syntax for basic operations with
>> dictionaries from stdlib's "dict" module. Dictionary construction and
>> accessing elements by keys are conceptually similar to record
>> construction and accessing record fields, however standard dictionary
>> interface is rather cumbersome compared to Erlang record syntax.
>>
>> I created a parse transformation to test this idea. This is a usage
>> example:
>>
>> -include_lib("erl_aliases.hrl").
>> -dict_alias('').
>> dict_alias_test() ->
>>    % creating an empty dictionary
>>    _ = #{},
>>
>>    % associating foo with 1
>>    D = #{foo = 1},
>>    1 = D.foo,
>>
>>    % setting foo to foo + 1 and baz to 100
>>    D1 = D#{foo = D.foo + 1}#{baz = 100},
>>    2 = D1.foo,
>>    100 = D1.baz,
>>
>>    % accessing undefined field
>>    {'EXIT', {badarg, _}} = (catch D.bar),
>>
>>    % several elements
>>    D2 = D#{bar = 1, fum = 10, obj = D},
>>    1 = D2.bar,
>>    10 = D2.fum,
>>
>>    % accessing field of a dict included in another dict
>>    1 = D2.obj.foo,
>>    ok.
>>
>> This is the result of the parse transformation:
>>
>> dict_alias_test() ->
>>    _ = dict:new(),
>>    D = dict:store(foo, 1, dict:new()),
>>    1 = dict:fetch(foo, D),
>>    D1 =
>>        dict:store(baz, 100, dict:store(foo, dict:fetch(foo, D) + 1, D)),
>>    2 = dict:fetch(foo, D1),
>>    100 = dict:fetch(baz, D1),
>>    {'EXIT',{badarg,_}} = (catch dict:fetch(bar, D)),
>>    D2 = dict:store(obj, D, dict:store(fum, 10, dict:store(bar, 1, D))),
>>    1 = dict:fetch(bar, D2),
>>    10 = dict:fetch(fum, D2),
>>    1 = dict:fetch(foo, dict:fetch(obj, D2)),
>>    ok.
>>
>> Note that in the beginning I defined a dict alias for an empty atom:
>> -dict_alias(''). If any other non-empty atom is used, then dictionary
>> construction and element access look exactly as correspondent record
>> operations. For example, with -dict_alias(dict), #dict{} will be
>> transformed to dict:new(), X#dict.a -- to dict:fetch(a, X) and so on.
>> This was the original idea, but then I discovered that it is possible
>> to get rid of record names, i.e. use #{} instead of #dict{} and X.foo
>> instead of X#dict.foo, etc. This, however, required definition of
>> three extra Yecc rules in erl_parse.yrl to handle expressions like
>> #{...}.
>>
>> Obviously, such parse transformations work only with expressions --
>> they are not applied to guards and patterns.
>>
>> The code is on GitHub (https://github.com/alavrik/erl_aliases), but
>> this functionality is not documented yet.
>>
>> Overall, this looks pretty neat to me. Beyond simple use, I'm
>> thinking, for example, about converting arbitrary JSON objects to
>> dictionaries and then accessing their contents using this method.
>> Parsed JSON object keys can be converted to atoms using
>> binary_to_existing_atom.
>>
>> What do you think? Is there anything I'm missing here that makes such
>> parse transformation potentially unreliable?
>>
>> Anton
>>
>> ________________________________________________________________
>> erlang-questions (at) erlang.org mailing list.
>> See http://www.erlang.org/faq.html
>> To unsubscribe; mailto:
>>
>>
>
>
> --
> Be well,
> andy
>
> Welcome to http://householder-yogi.net
> On family, NYC, and practicing yoga.
>


More information about the erlang-questions mailing list