<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 29, 2016 at 4:28 PM, Siraaj Khandkar <span dir="ltr"><<a href="mailto:siraaj@khandkar.net" target="_blank">siraaj@khandkar.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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) :)</blockquote></div><br>You are so close to the idea of view types, and Torben hinted me I should say something about them :)</div><div class="gmail_extra"><br></div><div class="gmail_extra">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.</div><div class="gmail_extra"><br></div><div class="gmail_extra">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:</div><div class="gmail_extra"><br></div><div class="gmail_extra">pth(X) -></div><div class="gmail_extra">    case http_uri:unfold_path(X) of</div><div class="gmail_extra">        none -> ...;</div><div class="gmail_extra">        {some, C, X2} -></div><div class="gmail_extra">           ... C ... pth(X2)</div><div class="gmail_extra">    end.</div><div class="gmail_extra"><br></div><div class="gmail_extra">or you can imagine a gb_trees/gb_sets like iterator over the data structure.</div><div class="gmail_extra"><br></div><div class="gmail_extra">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.</div><div class="gmail_extra"><br></div><div class="gmail_extra">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?</div><div class="gmail_extra"><br clear="all"><div><br></div>-- <br><div class="gmail_signature">J.</div>
</div></div>