Issue #16120 has been updated by jeremyevans0 (Jeremy Evans).


Dan0042 (Daniel DeLorme) wrote:
> @mame, The motivation of *this* proposal is related to the **side-by-side** proximity/repetition of `x` in `{|x|x.foo}`. Other proposals may be different. I can only guess at their true motivations. It just *seems* to me that the people asking for that kind of shorthand really intend to use it for `{|x|x.foo}` and just throw in `{|x|foo(x)}` because why not. But `@` is similar to `$_` in that it's only useful for debugging or throwaway code. `{.foo}` can actually be used in production code and make it clearer.

I disagree.  `{ foo(@) }` and `{ @.foo }` are not for debugging or throwaway code, they are natural replacements for `{ |x| foo(x) }` and `{|x| x.foo }`.  The `@` single implicit parameter approach is just as clear and is significantly more flexible than this approach (lacking a better name, the omitted parameter approach).

That's not to say the omitted parameter approach is bad.  In the cases it does handle, it does save a character compared to the implicit parameter approach.  I don't think that character saving makes the code clearer than the single implicit parameter approach, though.  In my opinion they are even in terms of clarity.

> The motivation for `(&JSON.:parse)`... honestly it seems like it's an entirely different beast. I don't think it's only about shortening the block. I have the feeling it's really about functional programming, and that `{JSON.parse(@)}` would not satistify the "requirement" for first-class functions. This one seems to be more about function composition, currying and whatnot, and less about avoiding verbosity.

I think the implicit parameter approach (`{JSON.parse(@)}`) is a simpler and more readable approach than the dot-colon approach (`(&JSON.:parse)`). Especially when you start function composition (`{JSON.parse(JSON.generate(@))}` vs `(&(JSON.:parse << JSON.:generate))`). Especially when you consider things like additional block arguments and keyword arguments (`:symbolize_keys`) passed to the methods.

> You make a painfully good point about how unendingly persistent these proposals are. But if the numbered parameter could really end the game, I'm quite sure there would not be so much opposition to it in #15723.

By "end the game", I think mame means that it is the most flexible approach, not necessarily the best approach.  And it doesn't really "end the game", as it doesn't handle block or keyword arguments :).

----------------------------------------
Feature #16120: Implicit block argument if block starts with dot-method call
https://bugs.ruby-lang.org/issues/16120#change-81071

* Author: Dan0042 (Daniel DeLorme)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
How about considering this syntax for implicit block parameter:
```
[10, 20, 30].map{ .to_s(16) }  #=> ["a", "14", "1e"]
```
Infinite thanks to @maedi for [the idea](https://bugs.ruby-lang.org/issues/15723#note-19)

This proposal is related to #4475, #9076, #10829, #12115, #15302, #15483, #15723, #15897, #16113 (and probably many others) which I feel are all trying to solve the same "problem". So I strongly believe all these feature requests should to be considered together in order to make a decision.

This "problem" can be more-or-less stated thus:
* There is a very common pattern in ruby: `posts.map{ |post| post.author.name }`
* In that line, the three 3 "post" in close proximity feel redundant and not DRY.
* To reduce the verbosity, people tend to use a meaningless one-character variable in the block
* But even so `posts.map{ |p| p.author.name }` still feels redundant.
* This "problem" is felt by many in the ruby community, and is the reason people often prefer `posts.map(&:author)`
* But that only works for one method with no arguments.
* This results in many requests for a block shorthand than can do more.

I realize that many people feel this is not a problem at all and keep saying "just use regular block syntax". But the repeated requests over the years, as well as the widespread usage of `(&:to_s)`, definitely indicate this is a wish/need for a lot of people.

Rather than adding to #15723 or #15897, I chose to make this a separate proposal because, unlike `it` or `@` implicit variables, it allows to simplify **only** `{ |x| x.foo }`, not `{ |x| foo(x) }`. This is on purpose and, in my opinion, a desirable limitation.

The advantages are (all in my opinion, of course)
* Extremely readable: `posts.map{ .author.name }`
   * Possibly even more than with an explicit variable.
* Of all proposals this handles the most important use-case with the most elegant syntax.
   * It's better to have a beautiful shorthand for 90% of cases than a non-beautiful shorthand for 100% of cases.
   * A shorthand notation is less needed for `{ |x| foo(x) }` since the two `x` variables are further apart and don't feel so redundant.
* No ascii soup
* No potential incompatibility like `_` or `it` or `item`
* Very simple to implement; there's just an implicit `|var| var` at the beginning of the block.
* In a way it's similar to chaining methods on multiple lines:

        posts.map{ |post| post
          .author.name
        }

It may be interesting to consider that the various proposals are not *necessarily* mutually exclusive. You *could* have `[1,2,3].map{ .itself + @ + @1 }`. Theoretically.

I feel like I've wanted something like this for most of the 16 years I've been coding ruby. Like... **this** is what I wanted that `(&:to_s)` could only deliver half-way. I predict that if this syntax is accepted, most people using `(&:to_s)` will switch to this.




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

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>