[erlang-questions] maps or records?

Benoit Chesneau bchesneau@REDACTED
Sat Mar 5 11:46:44 CET 2016


So I finally did it the old ways using records and accessor functions over
it. To answer to joe and other, the main goal was to have more clarity and
consistency over the time in the way you will access the data. Right now
the data structure is pretty clear  and can only be augmented if I have to
introduce new properties. So I guess it will be OK.

(this thread was very interesting to learn how others uses the records, we
should have more topics like this :) which let me remember
http://www.erlangpatterns.org/ ..., I wonder how the project works as of
today)

- benoit

On Tue, Mar 1, 2016 at 4:15 AM Siraaj Khandkar <siraaj@REDACTED> wrote:

> On 2/29/16 3:02 PM, Torben Hoffmann wrote:
> >
> >
> > Jesper Louis Andersen <jesper.louis.andersen@REDACTED> writes:
> >
> >> [ text/plain ]
> >> On Mon, Feb 29, 2016 at 4:28 PM, Siraaj Khandkar <siraaj@REDACTED>
> >> wrote:
> >>
> >>> 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) :)
> >>
> >>
> >> You are so close to the idea of view types, and Torben hinted me I
> should
> >> say something about them :)
> >>
> >> One advantage of a function is that it doesn't have to give you the
> field
> >> outright, but can provide ways to dynamically cast that structure into
> >> another structure you export. Two really good examples is that you can
> >> return some kind of tuple depending on the contents of the data and thus
> >> you can build a case match on the data. This ad-hoc
> >> for-the-purpose-construction of a datatype can often yield far more
> precise
> >> code since it splits analysis of what is *in* the datastructure from
> >> computation which says what to *do* about that data. Say we have a
> #uri{}
> >> record. The path component has many possible representations: a
> binary(), a
> >> list of binaries, an iterator, and so on. Different view-functions would
> >> give you different ways to handle that binary.
> >>
> >> Another nice thing is that functions can give you are
> >> zipper/derivative/delimiting-continuation over the data in the
> structure.
> >> The path-component can then be unfolded one path-entry at a time:
> >>
> >> pth(X) ->
> >>      case http_uri:unfold_path(X) of
> >>          none -> ...;
> >>          {some, C, X2} ->
> >>             ... C ... pth(X2)
> >>      end.
> >>
> >> or you can imagine a gb_trees/gb_sets like iterator over the data
> structure.
> >>
> >> A plain map() cannot give any of these ideas, and its transparency also
> >> tightly couples your code to the map() structure. So one has to
> carefully
> >> weigh what kind of interface you want in the long run. I much prefer
> views
> >> of the data structures if possible since it allows for more freedom in
> the
> >> long run, but it requires you to be able to figure out what kind of
> >> functions you would need a priori on the data. On the other hand, it
> >> provides for much better hiding of what is going on inside the module,
> >> which allows you more flexibility regarding backwards compatibility.
> >>
> >> In other words: exporting records across application boundaries tend to
> >> lock them down, so be pretty sure they are set in stone. Also think
> hard if
> >> you want every user to implement the analysis code. The view is much
> like
> >> in a database: do you export the raw records, or do you expose a
> >> transactional API through stored procedures which tell you what you can
> do
> >> with the data?
> >>
> >>
> > Why attempt to write a half-baked answer when you can ask Jesper to
> > explain it well?!?! [1]
> >
> > Look at Cowboy and Webmachine for examples of how to provide functions
> > to work with a request.
> >
> > Both have a very rich API for extracting relevant things out of the
> > request record.
> > No need to start poking into that record on your own.
> >
>
> I think you missed the point, see my reply to Jesper :)
>
> That said, since you bring-up Cowboy, it is a good example of what I
> mean by other constraints and plans - an author might want to fill-in
> some of the fields lazily (such body in cowboy_req), in which case
> per-field accessor functions are their only good choice, unless, of
> course, they want to consider compound subsets (of, say, only the
> eagerly calculated parts, but I digress - it isn't the important
> point)... :) Anyhow, without a specific application and vision for it's
> future, which API design direction to take is not something you or I can
> finalize here - it depends on a bunch of things.
>
> The important point is that, by using an abstract type, you're not at
> all limiting yourself to exposing per-field accessor functions - you can
> do other things (if you wish), as long as you make a clear distinction
> between internals and API.
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20160305/af7161dc/attachment.htm>


More information about the erlang-questions mailing list