From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: poffice@blade.nagaokaut.ac.jp Delivered-To: poffice@blade.nagaokaut.ac.jp Received: from kankan.nagaokaut.ac.jp (smtp.nagaokaut.ac.jp [133.44.2.24]) by blade.nagaokaut.ac.jp (Postfix) with ESMTP id 5B0BC19E003D for ; Mon, 28 Dec 2015 12:24:13 +0900 (JST) Received: from voscc.nagaokaut.ac.jp (voscc.nagaokaut.ac.jp [133.44.1.100]) by kankan.nagaokaut.ac.jp (Postfix) with ESMTP id C113CB5D872 for ; Mon, 28 Dec 2015 12:56:47 +0900 (JST) Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by voscc.nagaokaut.ac.jp (Postfix) with ESMTP id 260EC18CC7E2 for ; Mon, 28 Dec 2015 12:56:48 +0900 (JST) Received: from [221.186.184.76] (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 0D3D412055F; Mon, 28 Dec 2015 12:56:48 +0900 (JST) X-Original-To: ruby-core@ruby-lang.org Delivered-To: ruby-core@ruby-lang.org Received: from o10.shared.sendgrid.net (o10.shared.sendgrid.net [173.193.132.135]) by neon.ruby-lang.org (Postfix) with ESMTPS id A59821204FE for ; Mon, 28 Dec 2015 12:56:44 +0900 (JST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sendgrid.me; h=from:to:references:subject:mime-version:content-type:content-transfer-encoding:list-id; s=smtpapi; bh=nnSQfJ/BtBD0T6n8dD5l8zPU278=; b=iM8U0ag+Z4ZKgtM0Wn YfCljOREs+K1uqDHBYS+tbcGWAWDaciSByDvtKjFJHW+DxfubscMFKnQ9klaL8u6 VHuHV66P+4eG2dq/vfH3MJXhBFCQ4N4UyabzMwmjagKaebvtRWeviYbqAgnCsYzd COMQmJwKquaD5THkC5pw8onOw= Received: by filter0844p1mdw1.sendgrid.net with SMTP id filter0844p1mdw1.1282.5680B2F830 2015-12-28 03:56:40.89855706 +0000 UTC Received: from herokuapp.com (ec2-54-146-177-160.compute-1.amazonaws.com [54.146.177.160]) by ismtpd0003p1iad1.sendgrid.net (SG) with ESMTP id Lj-DvP_rRDCwjkT2GvIN4A Mon, 28 Dec 2015 03:56:40.906 +0000 (UTC) Date: Mon, 28 Dec 2015 03:56:40 +0000 From: shevegen@gmail.com To: ruby-core@ruby-lang.org Message-ID: References: Mime-Version: 1.0 X-Redmine-MailingListIntegration-Message-Ids: 47138 X-Redmine-Project: ruby-trunk X-Redmine-Issue-Id: 11882 X-Redmine-Issue-Author: hcatlin X-Redmine-Issue-Assignee: matz X-Redmine-Sender: shevegen X-Mailer: Redmine X-Redmine-Host: bugs.ruby-lang.org X-Redmine-Site: Ruby Issue Tracking System X-Auto-Response-Suppress: All Auto-Submitted: auto-generated X-SG-EID: ync6xU2WACa70kv/Ymy4QrNMhiuLXJG8OTL2vJD1yS6wXy49fV5uivJDoZnzYrnK3VCmmq9Mdq4u0/ 5hBaTST+JxUL9L+pB1lHfXDCKrEwqxIPDdJxeJjqoTHwtzK3aGB74UXGvsUIW1zZlkjaSunaU65Wxw zxSl3Xjc5ecso5D6vOWjH0YWU2RHmWWpgGCgFvKpG0qBDP6+Mor9OweZaw== X-ML-Name: ruby-core X-Mail-Count: 72538 Subject: [ruby-core:72538] [Ruby trunk - Feature #11882] Map or NamedMap X-BeenThere: ruby-core@ruby-lang.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: Ruby developers List-Id: Ruby developers List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ruby-core-bounces@ruby-lang.org Sender: "ruby-core" 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/