<br><br><div class="gmail_quote">On Thu, May 9, 2013 at 10:56 PM, Robert Virding <span dir="ltr"><<a href="mailto:robert.virding@erlang-solutions.com" target="_blank">robert.virding@erlang-solutions.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div style="font-size:12pt;font-family:times new roman,new york,times,serif">Even before taking a really deep dive into studying the EEP one thing I can immediately say: get rid of this having both <i>equal</i> and <i>match</i> and <b>USE ONLY MATCH. </b>Keys are the same when they match. Period. This paragraph:<br>
<br>If key <code>K</code> does not <em>equal</em> any existing key in the map, a new association
will be created from key <code>K</code> to value <code>V</code>.  If key <code>K</code> is <em>equal</em> to an existing
key in map <code>M</code> its associated value will be replaced by the new value <code>V</code> <em>and</em>
the new key <code>K</code> will replace the old key if the key does not <em>match</em>. In both
cases the evaluated map expression will return a new map.<br><br>is weird. Yes I know what it means but it is not intuitive. When keys are replaced or not replaced when they are equal is not can seem very strange to those not deep into erlang semantics. <br>
</div></div></blockquote><div><br></div><div>I think the problem here is the description - not the semantics. It's not the keys which are replaced, the crucial</div><div>idea is to have two different syntaxes. This needs a longer explanation to make sense.</div>
<div><br></div><div>Short explanation</div><div>==============</div><div><br></div><div>    ':=' means "update an existing key - crash if they key is not present"</div><div>    '=>' means "update an existing key OR add a new key" </div>
<div><br></div><div>The value is pretty much irrelevant</div><div><br></div><div>Long explanation of why this is good</div><div>=============================</div><div><br></div><div>We can update an existing map M with the syntax:</div>
<div><br></div><div>    M#{ K1 Op V1, K2 Op V2, ... Kn Op Vn}</div><div><br></div><div>Where Op is either => or :=.</div><div><br></div><div>The syntax K => V never generates an error and is used to introduce a new key</div>
<div>or to update an existing key with a new value.</div><div><br></div><div>The syntax K :=  V is used to update the value of an *existing* key and will</div><div>raise an exception if the key K does not already exist in the map M.</div>
<div><br></div><div>The difference between these two modes of update is crucial, but needs</div><div>a couple of examples to explain:</div><div><br></div><div>Assume we define a map M as follows:</div><div><br></div><div>
    M = #{ foo => 1, bar => 2, baz => 3 }</div><div><br></div><div><br></div><div>The update</div><div><br></div><div>    M # {foo := 12,  bary := 24}</div><div> </div><div>Will fail (raise an exception) since there is no key called bary in the</div>
<div>original map. This is good idea (ROK suggested this in his frames paper)</div><div>since we don't want too accidentally create a new key due to a spelling </div><div>error. This is the crash-early property of the := update syntax.</div>
<div><br></div><div>Crashing later would make debugging difficult, we would accidentally add</div><div>a bad key to a map and learn about it way later.</div><div><br></div><div>The update</div><div><br></div><div>   M # {foo := 12, bar := 24}</div>
<div><br></div><div>Will succeed, but more importantly the new map has exactly the same</div><div>keys as the old map (since all the updates are ':=' updates) - and so</div><div>can *share* the same key descriptor. So if we have a very long list of</div>
<div>maps they can be stored in a space efficient manner. (Again this idea</div><div>comes from ROKs frames paper). Björn-Egil's eep didn't mention this</div><div>but the fact that we know that two maps have the same keys from the</div>
<div>syntax make a lot of optimizations possible).</div><div><br></div><div>All of this is possible because there are two operators not one :-)</div><div><br></div><div>---</div><div><br></div><div>As regards efficiency, utility, beauty and so on these are subjective.</div>
<div><br></div><div>If you want the last ounce of efficiency records and dicts are not</div><div>going to go away when maps arrive. So if maps have the wrong</div><div>performance characteristics then use the exiting mechanisms.</div>
<div><br></div><div>In the latest addition of my book I've been documenting the changes to maps</div><div>- this chapter has changed three times and has tended to be conservative </div><div>so I haven't (yet) mentioned that keys can be any term (and not just atoms).</div>
<div><br></div><div>I'm rather looking forward to being able to represent things like XML</div><div>and JSON and property lists in a maps and to have an one-size-fits-all</div><div>replacement for dicts and records. I've never really worried about the</div>
<div>last ounce of efficiency - if I want real efficiency I'd change</div><div>language and go to C or program an FPGA.</div><div> </div><div>Cheers</div><div><br></div><div>/Joe</div><div><br></div><div><br></div><div>
<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div style="font-size:12pt;font-family:times new roman,new york,times,serif"><br>Push<br>Yes, I think we made an error with the different types of equalities and that comparisons covert integers to floats. With 20-20 hindsight I would prefer ==,/=,<,=<,>,>= to <b>ONLY</b> work on numbers and convert while another set @==,@/=,@<,@=<,@>,@>= (say) to work on terms and never convert.<br>
Pop<br><br>While we are at it I think the evaluation order for keys and values should be defined as left-to-right. The rest of erlang is so why not here?<br><br>Robert<br><br><hr><blockquote style="padding-left:5px;font-size:12pt;font-style:normal;margin-left:5px;font-family:Helvetica,Arial,sans-serif;text-decoration:none;font-weight:normal;border-left:2px solid #1010ff">
<b>From: </b>"Björn-Egil Dahlberg" <<a href="mailto:egil@erlang.org" target="_blank">egil@erlang.org</a>><div><div class="h5"><br><br>
  

    
  
  
    Hi everyone!
    <br>
    <br>
    We finally have a Maps EEP for you.
    This will get you an idea on what we are working on. Some of the
    ideas presented here was presented at Erlang Factory SF Bay Area
    2013.<br>
    <br>
    I am sure that there will be some discussions about the contents of
    this EEP and I hope the discussions will be both fruitful and
    civilized.
    <br>
    <br>
    The journey of Maps and this EEP has been long and by no means a
    straight-forward or continuous one. I had a crystal clear picture of
    what I wanted Maps to be when we first started discussing it within
    OTP about two-three years ago. This EEP resembles that vision but it
    has had a lot of contributions of other ideas from both within
    and outside of OTP.
    <br>
    <br>
    The idea was a functional data-type, a syntax aware mapping of
    key-value associations with pattern matching. A syntax similar to
    records but without the hazzle of compile-time dependency and with
    arbitrary terms as keys. Order was not important and it could be
    implemented with a Hash-Array-Mapped-Trie with good performance and
    memory trade-offs. This was not an approach to replace records. It
    was meant to replace records where suitable and in other regards not
    be a replacement but its own <b><span></span></b><span>thing</span><b><span></span></b>.
    <br>
    <br>
    From the community there has been many wishes of a Map like
    data-type and a few suggestions.  The one suggestion that stands out
    is of course the Frames proposal from Richard O'Keefe. It is the
    most complete proposal I've seen and is very well thought out. Its
    goal is to be a record replacement and the proposal satisfies this
    goal very well.
    <br>
    <br>
    - If Frames are that good, why a separate EEP?
    <br>
    - It boils down to goals and constraints.
    <br>
    <br>
    A record replacement is just that, a replacement.
    <br>
    It's like asking the question, "What do we have?" instead of "What
    can we get?"<br>
    The instant rebuttal would be "What do we need?" I say Maps. <br>
    <br>
    Frames has certainly influenced Maps. In many regards Maps also
    encompasses Frames but Maps tries to do more. I think the most
    significant difference would be, arbitrary terms as keys and how
    many different keys we would have in a Map. In the end I believe
    they are two different things and have different goals. <br>
    <br>
    Some Notes and Disclaimers:
    <br>
    <br>
    Later iterations of Maps has gone through some changes, most
    significantly,
    <br>
    <br>
      * From a set of key-values to a ordered set of key-value
    associations
    <br>
    <br>
    I was originally against this change since it forces restrictions on
    the implementation and it illuminates the lack of distinction
    between arithmetic order and term order, i.e. the problem of mixing
    integer and float types as keys in a tree. However, I was later
    persuaded that key ordering is necessary. We have to respect the
    totalitarian order of terms.
    <br>
    <br>
    Considerations has been made on how to, if at all possible, apply
    Frames characteristics to Maps. Most significantly memory space and
    key-sharing characteristics. This is not detailed in the EEP though,
    just mentioned.<br>
    <br>
    The function interface has had many revisions as well. At some stage
    the API was considered to be a drop-in-replacement for `dict` and
    thus would have the same function-names. This goal/constraint was
    dropped by Technical Board decision recently.<br>
    <br>
    From the very beginning Maps was envisioned to have the ability to
    bind variables derived from the environment. Like this:
    <br>
    <br>
        function(K1, #{ K1 := K2, K2 := V }) -> V.
    <br>
    <br>
    This feature is a beast. Powerful and scary. It is not confined to
    only Maps but should also be applicable to other types as well:
    <br>
    <br>
        function(Skip, <<_:Skip/binary, Value:Size,
    _/bits>>, Size) -> Value.
    <br>
    <br>
    It is uncertain how effective such an implementation would be and in
    the end we might not want this feature at all.<br>
    <br>
    In this EEP we will describe syntax and semantics of Maps but very
    little is disclosed of its actual implementation. Current prototypes
    stems from using sparse tuples in a HAMT-like data structure and
    tuple-like data structures. The HAMT-like data structure is
    discontinued and will be replaced by some ordered tree.<br>
    <br>
    The proposal is included as an attachment but can also be viewed at
    this git-repository:<br>
    <a href="https://github.com/psyeugenic/eep/blob/egil/maps/eeps/eep-0043.md" target="_blank">https://github.com/psyeugenic/eep/blob/egil/maps/eeps/eep-0043.md</a><br>
    <br>
    <br>
    Regards,
    <br>
    Björn-Egil Dahlberg
    <br>
    Erlang/OTP
  

<br></div></div><div class="im">_______________________________________________<br>erlang-questions mailing list<br><a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br><a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
</div></blockquote><br></div></div><br>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br></blockquote></div><br>