[erlang-questions] maps or records?

Siraaj Khandkar <>
Mon Feb 29 16:28:25 CET 2016


On 2/29/16 10:14 AM, zxq9 wrote:
> On Monday 29 February 2016 11:51:00 Santiago Fernández wrote:
>> On Mon, Feb 29, 2016 at 9:21 AM, Benoit Chesneau <>
>> wrote:
>>
>>> I have a function hackney_url:parse_url() returning a record
>>> #hackney_url{} . This record can be used internally but also externally by
>>> the applications that need it. Which requires for now to include
>>> "hackney_lib.hrl" . The record will likely change. On the other hands I am
>>> not sure I like to have to import the include file to get its definition
>>> (or copy this definition in another file, or just use the tuple) .
>>
>>
>> You can provide functions to access data in #hackney_url{}, like this:
>>
>> hackney:get_host(Url)
>>
>> and it isn't required to include hackney_lib.hrl in client code.
>
> I generally prefer this in most cases (not all, though -- sometimes you really
> do want a big hash). The most important thing to me about it is that you can
> isolate your promises from your implementations over time. It is a little more
> work to set up, of course, but it prevents you and all your users from having
> to perform major project surgery if you wind up realizing that something else
> is really the way to structure the data.
>
> I'm not overly crazy about -type vs -opaque, but it really *is* nice sometimes
> to reap the benefits of paying for a solid data abstraction up front.
>
> But sometimes its totally overkill. Figuring out which situation you're in is
> the trick. And I'm terrible at it, so I prefer to err on the side of caution,
> but then project deadlines... (>.<)

I don't think [accessor functions vs record labels] is the right 
dichotomy in these sort of cases. The dichotomy is only that of [API vs 
internal representation]. You can just as well have a #bar{}, which is a 
public representation of hidden #foo{}; foo module then just defines 
foo:to_bar/1 function and you honor the structure of #bar{} just the 
same as you honor the names and signatures of functions in a public API. 
In #foo{}, you can then do whatever you want, without telling the users.

In other words, I'm saying it is very possible to have this cake (of 
public structure) and eat it too (in private, without anyone accessing 
the rapidly-changing, secret cream) :)


More information about the erlang-questions mailing list