ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: merch-redmine@jeremyevans.net
To: ruby-core@ruby-lang.org
Subject: [ruby-core:72534] [Ruby trunk - Feature #11882] Map or NamedMap
Date: Mon, 28 Dec 2015 01:42:02 +0000	[thread overview]
Message-ID: <redmine.journal-55799.20151228014201.902cb1e7f8bc8725@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-11882.20151226202830@ruby-lang.org

Issue #11882 has been updated by Jeremy Evans.


Hampton Catlin wrote:
> Requirements:
> 1) Doesn't break existing code
> 2) Doesn't totally destroy the parser
> 3) Seems simple to differentiate
> 4) Clear upgrade path

The proposal to treat  `meth {{k: v}}` as `meth(Map.new(k: v))` instead of the current behavior of `meth do {k: v} end` clearly breaks existing code, and a lot more of it than you probably expect, which definitely does not fulfill your first requirement.

I think a Map/NamedMap/SymbolHash data structure is useful in some cases, but I don't think it belongs in core, or that it should have syntax support.  Symbols and strings are different and should be used for different things.  This data structure may appear helpful to newcomers that don't understand the difference between symbols and strings, but recommending this data structure to them is a short term gain with long term costs, as it will take them longer to understand the difference between the two.

----------------------------------------
Feature #11882: Map or NamedMap
https://bugs.ruby-lang.org/issues/11882#change-55799

* Author: Hampton Catlin
* Status: Open
* Priority: Normal
* Assignee: Yukihiro Matsumoto
----------------------------------------
Hash is one of the best features of Ruby. I remember being so pleased when I first learned Ruby to find out that *anything* could be a key and that you could do some really clever things with scripts, if you key of non-traditional elements.

However, like many people, 10 years into using Ruby, I still am writing code to cast around symbols to strings and strings to symbols, just to use Hash as a more traditional dictionary, keyed with string-like values. And, explaining to a junior programmers why they broke the code by using a key of a different type... it's not the most elegant thing to have to explain over and over.

Several proposals exist for how to deal with this, and all have been rejected... however it doesn't seem like it's for essential reasons, more technical or syntactic issues. Coming up with syntax is something I quite enjoy (Sass/Haml), so I thought I'd make a pitch for it.

Requirements:
1) Doesn't break existing code
2) Doesn't totally destroy the parser
3) Seems simple to differentiate
4) Clear upgrade path

My proposal is to introduce an entirely different type of Hash, called a Map (or NamedMap, if that's too ambiguous), that requires a string-like key. There are no other types of keys allowed on this Hash, other than either strings or symbols. Internally, each key would be considered a symbol only.

~~~
map = Map.new(a: 2, b: 3)
map["a"] #=> 2
map[:a] #=> 2
~~~

Already, we're better than HashWithIndifferentAccess, as it's clearly a bit easier to type. ;)

What about a literal syntax?

~~~
map = {{a: 2}}
empty_map = {{}}
~~~

As far as I can tell in the Ruby-syntax style, this should be pretty easy to distinguish syntactically from both a regular hash literal and a block. Further, as almost every method's option hash is string-keyed, you could easily define this.

~~~
def my _method(arg1, options = {{}})
end
~~~

Immediately, you could deal with your options hash, and not have to stress about if the end user has passed in strings or symbols into the options.

It would be trivial to create a Map polyfill for most libraries to start using the non-literal version right away, as it would basically be HashWithIndifferentAccess, except we need to guarantee that the keys are string-like.

So, to sum up, we avoid the 'breaking other people's existing code' by introducing a new data-type, the literal syntax (I think) should be fairly easy to implement, and it makes a very natural keyed data object (e.g. Javascript Objects) and brings that to Ruby.






-- 
https://bugs.ruby-lang.org/

  parent reply	other threads:[~2015-12-28  1:09 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <redmine.issue-11882.20151226202830@ruby-lang.org>
2015-12-26 20:28 ` [ruby-core:72497] [Ruby trunk - Feature #11882] [Open] Map or NamedMap hcatlin
2015-12-26 20:57 ` [ruby-core:72498] [Ruby trunk - Feature #11882] " hcatlin
2015-12-27 22:13 ` [ruby-core:72526] " hcatlin
2015-12-28  1:42 ` merch-redmine [this message]
2015-12-28  3:30 ` [ruby-core:72536] " hcatlin
2015-12-28  3:56 ` [ruby-core:72538] " shevegen
2015-12-28  7:02 ` [ruby-core:72544] " matthew
2015-12-28 18:16 ` [ruby-core:72561] " rr.rosas
2016-01-30  4:08 ` [ruby-core:73596] " andrew

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=redmine.journal-55799.20151228014201.902cb1e7f8bc8725@ruby-lang.org \
    --to=ruby-core@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).