ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: shevegen@gmail.com
To: ruby-core@ruby-lang.org
Subject: [ruby-core:72538] [Ruby trunk - Feature #11882] Map or NamedMap
Date: Mon, 28 Dec 2015 03:56:40 +0000	[thread overview]
Message-ID: <redmine.journal-55802.20151228035639.6fc4e3c5fae56c0d@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-11882.20151226202830@ruby-lang.org

Issue #11882 has been updated by Robert A. Heiler.


I concur with Hampton Catlin for the most part (save for the
name "Map", that is not a good name IMO).

I assume that exposing Symbols was never directly the primary
design goal to be had; it came to be, and please feel free to
correct  me if I am incorrect, mostly because using Symbols would be
faster than Strings and I assume that especially rails had pushed
for it due to having found other problems lateron with their big
code base. (The rails users also originated HashWithIndifferentAccess
as far as I am aware, but that is an abomination to type. I would
never use such a long name, but I mentioned it because it also
taps into the question of "strings versus symbols" situation,
so this is a recurring theme.)

I do not have any particular route to recommend or partake in,
so I can't pick from the above selection nor can I really add
any myself, but I would like to say that I concur with Hampton
Catlin even if I am coming from a somewhat different angle.

To me, as a newbie (I still am a newbie really even after years,
but I am like a somewhat "competent" newbie by now), I don't really
want to have to think about whether I need to use Strings or
Symbols at all as identifiers. Don't get me wrong there, I actually
love Symbols for a completely odd reason - I can use :foo rather
than 'foo' so I can save one character! (I could also use ?foo 
but I find ? ugly and we have method names with ? and also 
ternary, I don't want to use so many ?; thankfully we have the
lonely-person-stares-at-dot operator rather than another ?
again)

But, from a conceptual point of view, when I am writing some
ruby scripts, having to wonder or ponder about whether to use
Symbols or Strings, I feel it adds a small layer of complexity
that should not really exist in the first place (from the
"human user perspective" that is; it's fine as an internal 
part of ruby).

The name "Map" is a bit weird though. Reason I dislike that
name is because we already have .map and my brain refers 
to .map in a completely different way (aka, "apply on each
element" mostly). And if I were to see Map.map I would want
to not like it.

> I guess I just see 95% of Hash usage being made up of instances
> where symbols and strings are treated equally, and compensating
> code is required at every step to ensure that. I find it odd
> that this is considered an edge-case.

Oh I know how you feel there. :)

I remember that in my cookbooks project, I am saving every program
as a yaml file, so all programs will be described via yaml. So
this is a "yaml database", ok flat files.

Then, when I wanted to access the giant hash that is created
by loading all yaml files, I had to wonder whether I want to
keep them saved as a string or as a symbol (the key identifiers,
e. g. "vim" versus :vim to access all information pertaining
to vim).

I do not remember which way I went offhand but whatever it was,
I decided that I will convert input to the target format anyway
(so either I am doing a .to_s or a .to_sym but it's an extra
step of thinking required that really does not help me a lot;
on the other hand, it also isn't something that is a huge
issue to me either, it's more a peculiarity).

Ruby 3.0 is in the pipeline!

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

* 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  3:24 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 ` [ruby-core:72534] " merch-redmine
2015-12-28  3:30 ` [ruby-core:72536] " hcatlin
2015-12-28  3:56 ` shevegen [this message]
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-55802.20151228035639.6fc4e3c5fae56c0d@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).