[#58149] [ruby-trunk - Feature #9076][Open] New one-argument block syntax: &. — "asterite (Ary Borenszweig)" <ary@...>

23 messages 2013/11/04

[#58176] [ruby-trunk - Bug #9082][Open] popen3 hangs when stderr gets lots of output — "rosenfeld (Rodrigo Rosenfeld Rosas)" <rr.rosas@...>

15 messages 2013/11/05

[#58207] [ruby-trunk - Bug #9089][Open] rb_fix2uint no longer raises a RangeError when given negative values — "NoKarma (Arthur Schreiber)" <schreiber.arthur@...>

9 messages 2013/11/06

[#58243] [ruby-trunk - Feature #9098][Open] Indent heredoc against the left margin by default when "indented closing identifier" is turned on. — "sikachu (Prem Sichanugrist)" <s@...>

24 messages 2013/11/09

[#58306] [ruby-trunk - Bug #9106][Open] 'gem install' doesn't copy .so files of ext libs — "tagomoris (Satoshi TAGOMORI)" <tagomoris@...>

15 messages 2013/11/13

[#58324] [ruby-trunk - Feature #9108][Open] Hash sub-selections — "wardrop (Tom Wardrop)" <tom@...>

28 messages 2013/11/14

[#58342] [ruby-trunk - Feature #9112][Open] Make module lookup more dynamic (Including modules into a module after it has already been included) — "PragTob (Tobias Pfeiffer)" <pragtob@...>

16 messages 2013/11/14

[#58350] [ruby-trunk - Feature #9113][Open] Ship Ruby for Linux with jemalloc out-of-the-box — "sam.saffron (Sam Saffron)" <sam.saffron@...>

59 messages 2013/11/15

[#58374] [ruby-trunk - Bug #9115][Open] Logger traps all exceptions; breaks Timeout — "cphoenix (Chris Phoenix)" <cphoenix@...>

10 messages 2013/11/16

[#58375] [ruby-trunk - Feature #9116][Open] String#rsplit missing — "artagnon (Ramkumar Ramachandra)" <artagnon@...>

12 messages 2013/11/16

[#58396] [ruby-trunk - Bug #9121][Open] [PATCH] Remove rbtree implementation of SortedSet due to performance regression — "xshay (Xavier Shay)" <contact@...>

15 messages 2013/11/18

[#58404] [ruby-trunk - Feature #9123][Open] Make Numeric#nonzero? behavior consistent with Numeric#zero? — "sferik (Erik Michaels-Ober)" <sferik@...>

40 messages 2013/11/18

[#58411] [ruby-trunk - Bug #9124][Open] TestSocket errors in test-all on Arch 64-bit — "jonforums (Jon Forums)" <redmine@...>

14 messages 2013/11/18

[#58438] [ruby-trunk - Bug #9129][Open] Regression in support for IPv6 literals in URIs with Net::HTTP — "kallistec (Daniel DeLeo)" <dan@...>

11 messages 2013/11/19

[#58545] [ruby-trunk - Feature #9145][Open] Queue#pop(true) return nil if empty instead of raising ThreadError — "jsc (Justin Collins)" <redmine@...>

9 messages 2013/11/24

[#58653] [ruby-trunk - Bug #9170][Open] Math.sqrt returns different types when mathn is included; breaks various gems - this bug can be reproduced in Ruby 1.8 as well — "kranzky (Jason Hutchens)" <JasonHutchens@...>

7 messages 2013/11/28

[ruby-core:58173] [ruby-trunk - Feature #9076] New one-argument block syntax: &.

From: "alexeymuranov (Alexey Muranov)" <redmine@...>
Date: 2013-11-05 21:39:30 UTC
List: ruby-core #58173
Issue #9076 has been updated by alexeymuranov (Alexey Muranov).


Ary,

as far as i understand, the ampersand is used with symbols and not with strings because method names and identifiers are symbols and not strings.  What follows after the colon is not the symbol's "content," but the symbol's "label" or "name."  Replacing a symbol's name with any other unique name should not change the "meaning" of the program.

Arbitrarily named variables are always "noise," they are price for intuitive and notational simplicity.  IMO, the only alternatives to using arbitrarily named variables are the following.

1. Use predefined implicitly bound variables, or "placeholders," similar to the meaning of `&` in you proposal.  To go further, why not to introduce `&1` or `a1` for the first argument, `&2` or `a2` for the second, etc.?  Then you would also be able to do, with your proposal:

  [1, 2, 3, 4].reduce &1 + &2

I do not think this would be a great idea.  But i agree that one-argument functions are in some sense special.

Your proposal seems to break existing rules for block syntax: curly braces or do..end, which always designate a block, are absent in your case.

Using "implicitly bound variable &" would not generalize well to more complicated situations and would be confusing: how to be with

  [1, 2, 3, 4].map 2 * &
  [1, 2, 3, 4].map &.foo(&)
  [1, 2, 3, 4].map &.foo([5, 6].map &.bar)

?

2. Use combinators like in combinatory logic (http://plato.stanford.edu/entries/logic-combinatory/).  It should be possible to introduce various operations of composition on procs and methods (see #6284 for example) to avoid using variables at all, but it will be verbose and not syntactic sugar at all.  This is clearly not what you are proposing.

3. Instead of writing text, draw graphs and represent argument bindings by arrows.

It looks to me like you are suggesting to use a random syntactic sugar for a random special case.  Apart from using `&` instead of an arbitrarily named variable, the main difference you introduce seems to be the absence of curly braces.  This looks to me more like an inconsistency than like an advantage.
----------------------------------------
Feature #9076: New one-argument block syntax: &.
https://bugs.ruby-lang.org/issues/9076#change-42760

Author: asterite (Ary Borenszweig)
Status: Feedback
Priority: Low
Assignee: 
Category: core
Target version: Next Major


Hello,

I'd like to introduce a new syntax for blocks that have one argument.

Currently you can do this:

[1, 2, 3].map &:to_s

With the proposed syntax this will be written as:

[1, 2, 3].map &.to_s

Instead of ":" we use a ".".

The idea is that this new syntax is just syntax sugar that is expanded by the parser to this:

[1, 2, 3].map { |arg| arg.to_s }

This new syntax allows passing arguments:

[1, 2, 3, 4].map &.to_s(2) #=> ["1", "10", "11", "100"]

It also allows chaining calls:

[1, 10, 100].map &.to_s.length #=> [1, 2, 3]

You can also use another block:

[[1, -2], [-3, -4]].map &.map &.abs #=> [[1, 2], [3, 4]]

Pros:
- Doesn't conflict with any existing syntax, because that now gives a syntax error, so it is available.
- Allows passing arguments and chaining calls
- It's *fast*: it's just syntax sugar. The "&:to_s" is slower because the to_proc method is invoked, you have a cache of procs, etc.
- It looks ok (in my opinion) and allows very nice functional code (like the last example).

Cons:
- Only supports one (implicit) argument. But this is the same limitation of "&:to_s". If you want more than one argument, use the traditional block syntax.
- It's a new syntax, so users need to learn it. But to defend this point, users right now need to understand the &:to_s syntax, which is hard to explain (this calls the "to_proc" method of Symbol, which creates a block... vs. "it's just syntax sugar for")

What do you think?

We are using this syntax in a new language we are doing, Crystal, which has a syntax very similar to Ruby, and so far we think it's nice, simple and powerful. You can read more about it here: http://crystal-lang.org/2013/09/15/to-proc.html


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

In This Thread