RFC Future Ruby hash literal syntax

REQUEST FOR COMMENTS: Change to future Ruby hash literal syntax

In 1.9, if you prefer to omit parentheses and you write this:

h = { a: Array.new 5, ‘A’, b: 0, c: 1 } # Syntax error

you will get a syntax error. The following works:

h = { a: Array.new(5, ‘A’), b: 0, c: 1 }

because the parser is not confused by the argument-separating comma
and the element-separating comma.

I propose that the owners consider changing the syntax.

ALTERNATIVE 1: Same input, different interpretation

If the scanner does lookahead and returns tASSOC_SEP for a comma
that is followed by a label, then there is no ambiguity.

ALTERNATIVE 2: Use ‘;’ to separate elements, use ‘,’ for arguments

h = { a: Array.new 5, ‘A’; b: 0; c: 1 } # Proposal 2

This avoids shift-reduce conflicts by a simple change to the assocs
production in parse.y, perhaps. Unfortunately the semicolon looks
strange, especially in array literals, when we address those, too.

ALTERNATIVE 3: Allow ‘;’ as an element separator, but keep ‘,’

h = { a: Array.new 5, ‘A’; b: 0, c: 1 } # Proposal 3

This does not break working code. It is like ‘or’ versus ‘||’,
and ‘do’ vs. ‘{’, i.e., same role, different precedence.

Good Afternoon,

On Mon, Nov 29, 2010 at 2:45 PM, Michael Kaelbling <
[email protected]> wrote:

because the parser is not confused by the argument-separating comma

This does not break working code. It is like ‘or’ versus ‘||’,
and ‘do’ vs. ‘{’, i.e., same role, different precedence.

I’d vote none of the above. That has got to be some of the ugliest
looking
ruby code I’ve ever seen. None of those concepts looks to be legible at
all.
Forget about what the parser handles…the human brain can’t make heads
nor
tails out of that stuff.

Is there honestly a use case that requires the code to be compacted into
that ugly a grouping of different concepts? I mean I can get the concept
that folks hate parentheses but you really couldn’t do this?

x = Array.new 5, ‘A’
h = { a: x, b: 0, c: 1 }

John

On Nov 29, 2010, at 14:58 , John W Higgins wrote:

x = Array.new 5, ‘A’
h = { a: x, b: 0, c: 1 }

or better:

h = { a: [“A”] * 5, b: 0, c: 1 }

I never understand ppl’s obsession with Array.new and Hash.new, not
including hash’s block initializer. Hash.new {…} is brilliant and I
love it. I think all variants or Array.new are essentially useless and
stick to [] for everything.

Most of my students who Array.new that were Java developers and it was
pretty easy to break them of the habit.

(and most of my students who obsessively used ‘’ instead of “” were
perlers… that was a harder habit to break, even if I could show them
that they were just as fast (and always faster than perl)).

On Nov 29, 2010, at 15:31 , Ryan D. wrote:

I never understand ppl’s obsession with Array.new and Hash.new, not including
hash’s block initializer. Hash.new {…} is brilliant and I love it. I think all
variants or Array.new are essentially useless and stick to [] for everything.

And, of course:

BenString.new(“my string is better with BenString”)

On Mon, Nov 29, 2010 at 3:58 PM, John W Higgins [email protected]
wrote:

I’d vote none of the above. That has got to be some of the ugliest looking
ruby code I’ve ever seen.

Ditto. Forget about shift/reduce conflicts… I don’t care if a parser
can’t
figure out so much as if my brain can’t figure out, and looking at your
examples I can’t tell what’s going on.

Replacing , with ; in the new hash literal syntax would be a bad change,
imo. The new hash literal syntax works well for keyword arguments and in
fact I’d consider that the main use case, e.g.

mymethod(arg1: x, arg2: y, arg3: z)

The idea being you could use this in lieu of:

mymethod(x, y, z)

so using a , is much more natural.

On Mon, Nov 29, 2010 at 6:49 PM, Ryan D.
[email protected]wrote:

And, of course:

BenString.new(“my string is better with BenString”)

Who uses string literals anymore? I switched to using BenStrings
exclusively.

On Nov 29, 2010, at 19:40 , Yossef M. wrote:

On Nov 29, 5:31 pm, Ryan D. [email protected] wrote:

I think all variants or Array.new are essentially useless and stick to [] for
everything.

What’s your [] equivalent of Array.new(3) { Thing.new }?

BenArray.new(3, Thing.new) works great!

On Nov 29, 5:31pm, Ryan D. [email protected] wrote:

I think all variants or Array.new are essentially useless and stick to [] for
everything.

What’s your [] equivalent of Array.new(3) { Thing.new }?

On Nov 29, 9:48pm, Ryan D. [email protected] wrote:

On Nov 29, 2010, at 19:40 , Yossef M. wrote:

On Nov 29, 5:31 pm, Ryan D. [email protected] wrote:

I think all variants or Array.new are essentially useless and stick to [] for
everything.

What’s your [] equivalent of Array.new(3) { Thing.new }?

BenArray.new(3, Thing.new) works great!

I’ve yet to use BenArray, but assuming it follows BenString
conventions:

Array.new(3, Object.new)
=> [#Object:0x51af7c, #Object:0x51af7c, #Object:0x51af7c]
Array.new(3) { Object.new }
=> [#Object:0x5136b4, #Object:0x5136a0, #Object:0x51363c]

My question still stands.

On Mon, Nov 29, 2010 at 8:40 PM, Yossef M.
[email protected]wrote:

On Nov 29, 5:31 pm, Ryan D. [email protected] wrote:

I think all variants or Array.new are essentially useless and stick to []
for everything.

What’s your [] equivalent of Array.new(3) { Thing.new }?

Using an inline block like that mandates parens around the argument(s)
anyway so it’s moot in this context.

ruby-1.9.2-p0 > ([1]*3).map! {|x| Object.new}
=> [#Object:0x00000000a12778, #Object:0x00000000a12750,
#Object:0x00000000a12728]

??

On Mon, Nov 29, 2010 at 9:36 PM, Sam D. [email protected]
wrote:

Oops, just realised I didn’t need the x

ruby-1.9.2-p0 > ([1]*3).map! {Object.new}
=> [#Object:0x00000000a4b848, #Object:0x00000000a4b820,
#Object:0x00000000a4b7f8]

You don’t need the map! either, and while I’m at it…

(1..3).map { Object.new }

Oops, just realised I didn’t need the x

ruby-1.9.2-p0 > ([1]*3).map! {Object.new}
=> [#Object:0x00000000a4b848, #Object:0x00000000a4b820,
#Object:0x00000000a4b7f8]

Sam

On Tue, Nov 30, 2010 at 12:41 PM, Tony A. [email protected]
wrote:

(1…3).map { Object.new }

i’d do,

3.times.map{Object.new}
#=> [#Object:0x94df234, #Object:0x94df220, #Object:0x94df20c]

since when read, i feel it would be closer to Array.new(3){Object.new}
but i have no qualms about Array.new notations though and i used them
all the time :slight_smile:

best regards -botp

On Nov 29, 11:05pm, botp [email protected] wrote:

i’d do,

3.times.map{Object.new}
#=> [#Object:0x94df234, #Object:0x94df220, #Object:0x94df20c]

I wasn’t aware that was possible, but it makes sense since 3.times
returns an enumerator.

It’s also the only example that doesn’t feel like an overt attempt to
avoid using the right tool for the job.

Tony A. wrote in post #965007:

What’s your [] equivalent of Array.new(3) { Thing.new }?

Using an inline block like that mandates parens around the argument(s)
anyway so it’s moot in this context.

Parens not needed with do/end:

class Thing; end
=> nil

a = Array.new 3 do Thing.new end
=> [#Thing:0x7f69a1a5e210, #Thing:0x7f69a1a5e1e8,
#Thing:0x7f69a1a5e198]

On Nov 29, 2010, at 19:54 , Yossef M. wrote:

I’ve yet to use BenArray, but assuming it follows BenString
conventions:

Array.new(3, Object.new)
=> [#Object:0x51af7c, #Object:0x51af7c, #Object:0x51af7c]

Array.new(3) { Object.new }
=> [#Object:0x5136b4, #Object:0x5136a0, #Object:0x51363c]

My question still stands.

No! BenArray performs like the latter.

On Mon, Nov 29, 2010 at 9:40 PM, Yossef M.
[email protected]wrote:

On Nov 29, 5:31 pm, Ryan D. [email protected] wrote:

I think all variants or Array.new are essentially useless and stick to []
for everything.

What’s your [] equivalent of Array.new(3) { Thing.new }?


-yossef

Don’t even need to go that far, even the String version has this issue.

a = [‘A’] * 5
a.first << ‘B’
a # => [“AB”, “AB”, “AB”, “AB”, “AB”]

On Nov 30, 4:19pm, Ryan D. [email protected] wrote:

On Nov 29, 2010, at 19:54 , Yossef M. wrote:

I’ve yet to use BenArray, but assuming it follows BenString
conventions:

No! BenArray performs like the latter.

For communication’s sake, I suggest you make special cases like that
clear in the future.

On Dec 1, 2010, at 11:54 , Yossef M. wrote:

On Nov 30, 4:19 pm, Ryan D. [email protected] wrote:

On Nov 29, 2010, at 19:54 , Yossef M. wrote:

I’ve yet to use BenArray, but assuming it follows BenString
conventions:

No! BenArray performs like the latter.

For communication’s sake, I suggest you make special cases like that
clear in the future.

I did. “Ben”