https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112013-11-04T23:42:35ZRuby Issue Tracking SystemRuby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427402013-11-04T23:42:35ZHanmac (Hans Mackowiak)hanmac@gmx.de
<ul></ul><p>my first idea is this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Symbol</span>
<span class="k">def</span> <span class="nf">call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="nb">proc</span> <span class="p">{</span><span class="o">|</span><span class="n">obj</span><span class="o">|</span> <span class="n">obj</span><span class="p">.</span><span class="nf">public_send</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span><span class="o">*</span><span class="n">args</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">].</span><span class="nf">map</span> <span class="o">&</span><span class="ss">:to_s</span><span class="o">.</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="c1"># => ["1", "10", "11", "100"] </span>
</code></pre>
<p>it is not chainable yet but its a nice beginning (and already valid ruby code)</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427412013-11-05T00:55:32Zshevegen (Robert A. Heiler)shevegen@gmail.com
<ul></ul><p>I dislike the amount of special meanings that would get associated with <code>&</code> and I already think that <code>&</code> is used too much.</p>
<p>Every new syntax increases the complexity of the language. Rather than extend on <code>&</code>, I'd rather remove the meaning of <code>&</code> in regards to call <code>to_proc</code> anyway - how great it would be if we could remove <code>&</code> altogether from ruby!</p>
<p>I will also tell you what happens once that syntax is in place:</p>
<p>People will come to IRC and ask what the difference is between <code>&:to_s</code> and <code>&.to_s</code>, just as they currently do all the time when they ask "what is the difference between a symbol and a string?"</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427422013-11-05T00:57:12Zshevegen (Robert A. Heiler)shevegen@gmail.com
<ul></ul><p>Note that if <code>&:</code> would be removed at the same time and <code>&.</code> added I would not mind it that much. You could use <code>&</code> as a reference to a global object, just similar to how <code>$1</code> or <code>$2</code> is automagically set for regexes. But to keep two different syntaxes for semi-similar issues is very bad.</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427432013-11-05T05:29:36Zfuadksd (Fuad Saud)fuadksd@gmail.com
<ul></ul><p>Introducing both syntaxes indeed is a bit confusing. I don’t think</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">100</span><span class="p">].</span><span class="nf">map</span> <span class="o">&</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">length</span>
</code></pre>
<p>is much better than</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">100</span><span class="p">].</span><span class="nf">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="n">i</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">length</span> <span class="p">}</span>
</code></pre>
<p>I think the latter is clearer. I'm fond of having some sugar for positional parameter access (like % in clojure or & in elixir), though.</p>
<p>--<br>
Fuad Saud<br>
Sent with Sparrow (<a href="http://www.sparrowmailapp.com/?sig" class="external">http://www.sparrowmailapp.com/?sig</a>)</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427442013-11-05T05:59:31Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Feedback</i></li><li><strong>Priority</strong> changed from <i>Normal</i> to <i>3</i></li><li><strong>Target version</strong> changed from <i>2.1.0</i> to <i>3.0</i></li></ul><p>You seem confusing that <code>&:</code> is an operator, but it's not.<br>
They are <code>&</code> + <code>:</code> of the beginning of a symbol literal.<br>
To make <code>&.to_s</code> valid, <code>.to_s</code> needs to be valid solely.</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427452013-11-05T06:17:10Zasterite (Ary Borenszweig)asterite@gmail.com
<ul></ul><p>nobu (Nobuyoshi Nakada) wrote:</p>
<blockquote>
<p>You seem confusing that <code>&:</code> is an operator, but it's not<br>
They are <code>&</code> + <code>:</code> of the beginning of a symbol literal.</p>
</blockquote>
<p>I know. I don't think I'm confusing them.</p>
<blockquote>
<p>To make <code>&.to_s</code> valid, <code>.to_s</code> needs to be valid solely.</p>
</blockquote>
<p>I don't see why ".to_s" needs to be valid solely.</p>
<p>In my proposal the new keyword is <code>&.</code>. The parser needs to be modified so that when you have a block argument, if a <code>.</code> comes after the <code>&</code> (something which is currently illegal) then it tries to parse a method call after the dot, and then it transforms the block argument to a regular block.</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427462013-11-05T06:57:02Zalexeymuranov (Alexey Muranov)
<ul></ul><p>In my opinion, this is a bad idea: there would be a dot <code>.</code>, an ampersand <code>&</code>, and an ampersand-dot <code>&.</code>, unrelated to either of the two.</p>
<p>What is wrong with <code>[1, 2, 3, 4].map{|x| x.to_s(2)}</code>?</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427502013-11-05T11:59:48Zasterite (Ary Borenszweig)asterite@gmail.com
<ul></ul><p>alexeymuranov (Alexey Muranov) wrote:</p>
<blockquote>
<p>In my opinion, this is a bad idea: there would be a dot <code>.</code>, an ampersand <code>&</code>, and an ampersand-dot <code>&.</code>, unrelated to either of the two.</p>
<p>What is wrong with <code>[1, 2, 3, 4].map{|x| x.to_s(2)}</code>?</p>
</blockquote>
<p>The "x" variable is just noise. What you want to do in that line of code is "map every element with a call to <code>to_s(2)</code>". With an "x" what you read is "let x be each element of this array, then invoke <code>to_s(2)</code> on it...". The first sentence is shorter and clearer on the mind.</p>
<p>This is why people tend to do <code>&:to_s</code> instead of <code>{|x| x.to_s}</code>. The later just adds noise.</p>
<p>However, what does a Symbol has to do there? Why doesn't it work with a String, like <code>&"to_s"</code>? Well, because it's just a hack. It's an abuse of the language. And that abuse not only comes with a hard explanation (it calls the <code>to_proc</code> method on Symbol to turn it into a Proc) but also with a performance penalty.</p>
<p>By using <code>&.to_s</code> you get 1. no performance penalty, 2. a chainable syntax, 3. an easier way to explain it (it's just syntax sugar for a single argument block, where you invoke a method on it).</p>
<p>But maybe its too late to add it now to the language... nobody seems to like it or see its advantages.</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427552013-11-05T18:01:26ZHanmac (Hans Mackowiak)hanmac@gmx.de
<ul></ul><p>i got a working sample with <code>.()</code></p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Symbol</span>
<span class="k">class</span> <span class="nc">SymbolHelper</span> <span class="o"><</span> <span class="no">BasicObject</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span><span class="n">methId</span><span class="p">,</span><span class="o">*</span><span class="n">args</span><span class="p">,</span><span class="o">&</span><span class="n">blk</span><span class="p">)</span>
<span class="vi">@obj</span> <span class="o">=</span> <span class="n">obj</span>
<span class="vi">@methId</span> <span class="o">=</span> <span class="n">methId</span>
<span class="vi">@args</span> <span class="o">=</span> <span class="n">args</span>
<span class="vi">@blk</span> <span class="o">=</span> <span class="n">blk</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="n">methId</span><span class="p">,</span><span class="o">*</span><span class="n">args</span><span class="p">,</span><span class="o">&</span><span class="n">blk</span><span class="p">)</span>
<span class="k">return</span> <span class="no">SymbolHelper</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span><span class="n">methId</span><span class="p">,</span><span class="o">*</span><span class="n">args</span><span class="p">,</span><span class="o">&</span><span class="n">blk</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">to_proc</span>
<span class="o">::</span><span class="no">Kernel</span><span class="o">::</span><span class="nb">proc</span> <span class="p">{</span><span class="o">|</span><span class="n">obj</span><span class="o">|</span> <span class="p">(</span><span class="vi">@obj</span> <span class="o">==</span> <span class="kp">nil</span> <span class="p">?</span> <span class="n">obj</span> <span class="p">:</span> <span class="vi">@obj</span><span class="p">.</span><span class="nf">to_proc</span><span class="o">.</span><span class="p">(</span><span class="n">obj</span><span class="p">)).</span><span class="nf">public_send</span><span class="p">(</span><span class="vi">@methId</span><span class="p">,</span><span class="o">*</span><span class="vi">@args</span><span class="p">,</span><span class="o">&</span><span class="vi">@blk</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span><span class="o">&</span><span class="n">blk</span><span class="p">)</span>
<span class="k">return</span> <span class="no">SymbolHelper</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="kp">nil</span><span class="p">,</span><span class="nb">self</span><span class="p">,</span><span class="o">*</span><span class="n">args</span><span class="p">,</span><span class="o">&</span><span class="n">blk</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">].</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:to_s</span><span class="o">.</span><span class="p">(</span><span class="mi">2</span><span class="p">))</span> <span class="c1">#=> ["1", "10", "11", "100", "101"]</span>
<span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">].</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:to_s</span><span class="o">.</span><span class="p">(</span><span class="mi">2</span><span class="p">).</span><span class="nf">size</span><span class="p">)</span> <span class="c1"># => [1, 2, 2, 3, 3]</span>
<span class="p">[[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">],[</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">],[],[</span><span class="mi">2</span><span class="p">]].</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:any?</span><span class="o">.</span><span class="p">(</span><span class="o">&</span><span class="ss">:even?</span><span class="p">))</span> <span class="c1">#=> [true, false, false, true] </span>
</code></pre>
<p>i hope that suits you guys</p>
<p>Edit: added blk</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427582013-11-05T20:08:52Zasterite (Ary Borenszweig)asterite@gmail.com
<ul></ul><p>Hanmac: thanks for the code to make it work. Ruby is very powerful.</p>
<p>However, I'm sure that code is very slow. At least slower than writing a block. That's why I'm not interested in any code that can make it work, because it will always be slower than syntax sugar.</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427602013-11-06T06:39:29Zalexeymuranov (Alexey Muranov)
<ul></ul><p>Ary,</p>
<p>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.</p>
<p>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.</p>
<ol>
<li>
<p>Use predefined implicitly bound variables, or "placeholders," similar to the meaning of <code>&</code> in you proposal. To go further, why not to introduce <code>&1</code> or <code>a1</code> for the first argument, <code>&2</code> or <code>a2</code> for the second, etc.? Then you would also be able to do, with your proposal:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">].</span><span class="nf">reduce</span> <span class="o">&</span><span class="mi">1</span> <span class="o">+</span> <span class="o">&</span><span class="mi">2</span>
</code></pre>
<p>I do not think this would be a great idea. But i agree that one-argument functions are in some sense special.</p>
<p>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.</p>
<p>Using "implicitly bound variable &" would not generalize well to more complicated situations and would be confusing: how to be with</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">].</span><span class="nf">map</span> <span class="mi">2</span> <span class="o">*</span> <span class="o">&</span>
<span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">].</span><span class="nf">map</span> <span class="o">&</span><span class="p">.</span><span class="nf">foo</span><span class="p">(</span><span class="o">&</span><span class="p">)</span>
<span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">].</span><span class="nf">map</span> <span class="o">&</span><span class="p">.</span><span class="nf">foo</span><span class="p">([</span><span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">].</span><span class="nf">map</span> <span class="o">&</span><span class="p">.</span><span class="nf">bar</span><span class="p">)</span>
</code></pre>
<p>?</p>
</li>
<li>
<p>Use combinators like in combinatory logic (<a href="http://plato.stanford.edu/entries/logic-combinatory/" class="external">http://plato.stanford.edu/entries/logic-combinatory/</a>). It should be possible to introduce various operations of composition on procs and methods (see <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Add composition for procs (Closed)" href="https://redmine.ruby-lang.org/issues/6284">#6284</a> for example) to avoid using variables at all, but it will be verbose and not syntactic sugar. This is clearly not what you are proposing.</p>
</li>
<li>
<p>Instead of writing text, draw graphs and represent argument bindings by arrows.</p>
</li>
</ol>
<p>It looks to me like you are suggesting to use a random syntactic sugar for a random special case. Apart from using <code>&</code> 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.</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427812013-11-06T21:53:42Zasterite (Ary Borenszweig)asterite@gmail.com
<ul></ul><p>Alexey,</p>
<p>You are right about every point you make. It's indeed a random syntactic sugar for a special case. It only happens that that special case happens very often. Otherwise Symbol#to_proc, <code>&:to_s</code>, wouldn't exist.</p>
<p>Note that in doing <code>array.map &:to_s</code> the <code>do ... end</code> and curly braces are also missing. However, the <code>&</code> signals a block, just as when you do <code>foo &block</code>. This is no different than <code>foo &.something</code> where, again, the <code>&</code> signals a block.</p>
<p>However, you are right that a more powerful solution allowing you to refer to any of the block's arguments, not just the first one, would be much nicer. But I think this is harder because when you have nested blocks then how you refer to arguments in the parent block? A syntax like <code>&&1</code> comes to my mind... Mmm... Just kidding :-)</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427822013-11-06T22:44:05Zalexeymuranov (Alexey Muranov)
<ul></ul><blockquote>
<p>Note that in doing <code>array.map &:to_s</code> the <code>do ... end</code> and curly braces are also missing. However, the <code>&</code> signals a block, just as when you do <code>foo &block</code>. This is no different than <code>foo &.something</code> where, again, the <code>&</code> signals a block.</p>
</blockquote>
<p>Ary, in <code>array.map &:to_s</code> curly braces are missing because there is no literal block definition, the block is the result of the <code>&</code> operator applied to a symbol.</p>
<p>The main problem IMO with your proposed syntactic sugar for the common special case is that it adds a completely new syntactic rule to Ruby, and also breaks one or more of existing ones. Normally in Ruby</p>
<pre><code><method_name1> <identifier1>.<method_name2>.<method_name3>
</code></pre>
<p>means: "call the method named by <code><method_name2></code> on the object named by <code><identifier1></code> or value returned by the method <code><identifier1></code>, then call the method named <code><method_name3></code> on the result, then yield the result as the argument to a call of the method named by <code><method_name1></code>"</p>
<p>(I am not a specialist, i am not sure i am using all the terms correctly.)</p>
<p>It seems to me that what you are looking for is probably a shorter notation for a one-argument lambda or block. I personally doubt that there is much space in Ruby syntax to introduce it.</p>
<p>Skipping the curly braces does not look to me like a benefit and may make the syntax ambiguous or not flexible.</p>
<p>The performance penalty of the <code>&</code> operator probably can be worked around by compiling the code.</p>
<p>Avoiding the hassle of naming the bound variable IMHO is not ... worth the hassle. :) Well, if i really wanted that myself, i might have proposed something like</p>
<pre><code>[1, 2, 3, 4].map { ..to_s(2) }
[1, 2, 3, 4].map { ..foo([5, 6].map { ..bar }) } # the argument is shadowed
</code></pre>
<p>o_O</p>
<p><em>Edited 2013-11-09</em></p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427832013-11-06T23:22:09Zasterite (Ary Borenszweig)asterite@gmail.com
<ul></ul><p>alexeymuranov (Alexey Muranov) wrote:</p>
<blockquote>
<blockquote>
<p>Note that in doing <code>array.map &:to_s</code> the <code>do ... end</code> and curly braces are also missing. However, the <code>&</code> signals a block, just as when you do <code>foo &block</code>. This is no different than <code>foo &.something</code> where, again, the <code>&</code> signals a block.</p>
</blockquote>
<p>Ary, in <code>array.map &:to_s</code> curly braces are missing because there is no literal block definition, the block is the result of the <code>&</code> operator applied to a symbol.</p>
</blockquote>
<p>I know.</p>
<p>Did you know that you can't do <code>&:to_s</code> wherever you want?</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">001</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="o">&</span><span class="ss">:to_s</span>
<span class="no">SyntaxError</span><span class="p">:</span> <span class="p">(</span><span class="n">irb</span><span class="p">):</span><span class="mi">1</span><span class="p">:</span> <span class="n">syntax</span> <span class="n">error</span><span class="p">,</span> <span class="n">unexpected</span> <span class="n">tAMPER</span>
<span class="o">&</span><span class="ss">:to_s</span>
<span class="o">^</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">002</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="n">a</span> <span class="o">=</span> <span class="o">&</span><span class="ss">:to_s</span>
<span class="no">SyntaxError</span><span class="p">:</span> <span class="p">(</span><span class="n">irb</span><span class="p">):</span><span class="mi">2</span><span class="p">:</span> <span class="n">syntax</span> <span class="n">error</span><span class="p">,</span> <span class="n">unexpected</span> <span class="n">tAMPER</span>
<span class="n">a</span> <span class="o">=</span> <span class="o">&</span><span class="ss">:to_s</span>
<span class="o">^</span>
</code></pre>
<p>That means, Ruby only recognizes <code>&<expression></code> as the last argument to a call. That also means that the <code>&</code> operator can only mean a block, somehow. Similarly, <code>&.</code> will mean a block with the semantics I already explained.</p>
<blockquote>
<p>The main problem IMO with your proposed syntactic sugar for the common special case is that it adds a completely new syntactic rule to Ruby, and also breaks one or more of existing ones.</p>
</blockquote>
<p>No, it doesn't break anything because right now that <code>&.to_s</code> gives syntax error, which means that syntax is available for defining new meanings.</p>
<p>Normally in Ruby</p>
<blockquote>
<pre><code><method_name1> <identifier1>.<method_name2>.<method_name3>
</code></pre>
<p>means: "call the method named by <method_name2> on the object named by or value returned by the method , then call the method named <method_name3> on the result, then yield the result as the argument to a call of the method named by <method_name1>"</p>
<p>(I am not a specialist, i am not sure i am using all the terms correctly.)</p>
<p>It seems to me that what you are looking for is probably a shorter notation for a one-argument lambda. I personally doubt that there is much space in Ruby syntax to introduce it.</p>
</blockquote>
<p>As I said, there <em>is</em> space in Ruby syntax for it, precisely because right now it's a syntax error.</p>
<blockquote>
<p>Skipping the curly braces does not look to me like a benefit and may make the syntax ambiguous or not flexible.</p>
</blockquote>
<p>When you do <code>map &:to_s</code> you are skipping the curly braces.</p>
<blockquote>
<p>The performance penalty of the <code>&</code> operator probably can be worked around by compiling the code.</p>
</blockquote>
<p>What do you mean?</p>
<p>I think this can be done by Ruby, yes: just make <code>a.map &:to_s</code> be the same as <code>a.map { |x| x.to_s }</code> by the parser... I think they are discussing similar things to do related to frozen strings.</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=427842013-11-06T23:32:43Zalexeymuranov (Alexey Muranov)
<ul></ul><p>asterite (Ary Borenszweig) wrote:</p>
<blockquote>
<p>Did you know that you can't do <code>&:to_s</code> wherever you want?</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">001</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="o">&</span><span class="ss">:to_s</span>
<span class="no">SyntaxError</span><span class="p">:</span> <span class="p">(</span><span class="n">irb</span><span class="p">):</span><span class="mi">1</span><span class="p">:</span> <span class="n">syntax</span> <span class="n">error</span><span class="p">,</span> <span class="n">unexpected</span> <span class="n">tAMPER</span>
<span class="o">&</span><span class="ss">:to_s</span>
<span class="o">^</span>
</code></pre>
</blockquote>
<p>Yes, this is because blocks do not exist as objects in Ruby, they appear and are evaluated or captured in procs during method calls. So the result of <code>&</code> cannot be stored in a variable, it has to be run or converted to a proc.</p>
<blockquote>
<p>When you do <code>map &:to_s</code> you are skipping the curly braces.</p>
</blockquote>
<p>I am not skipping curly braces, i am just not defining any block, it is obtained by the <code>&</code> operator.</p>
<blockquote>
<blockquote>
<p>The performance penalty of the <code>&</code> operator probably can be worked around by compiling the code.</p>
</blockquote>
<p>What do you mean?</p>
<p>I think this can be done by Ruby, yes: just make <code>a.map &:to_s</code> be the same as <code>a.map { |x| x.to_s }</code> by the parser... I think they are discussing similar things to do related to frozen strings.</p>
</blockquote>
<p>Yes, this is what i mean.</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=455732014-03-02T12:09:54Zsowieso (So Wieso)sowieso@dukun.de
<ul></ul><p>I think this would be a really great idea.<br>
<code>Symbol#to_proc</code> is technically a nice solution, but not nice from the esthetically viewpoint. Just have a look how many people are confused by this.<br>
<code>&.a_method</code> makes immediately clear that here a method call is happening. So <code>&</code> must be a (special) object. Context makes pretty clear which object that is, even if you do not know this syntax rule.<br>
I agree that having two solutions is not nice, but only because we implemented a weak solution we should not restrict ourselves to it as there are mightier and more readable ones.</p>
<p>I'd like to remark, that getting a solution that solves this issue once and for all in official ruby would be much nicer than the current half-hearted <code>.to_proc</code> hack. There are many projects in the Internet that tried to solve this, thus demand is given. Let's unify them!<br>
<a href="https://github.com/rapportive-oss/ampex" class="external">https://github.com/rapportive-oss/ampex</a><br>
<a href="https://github.com/danielribeiro/RubyUnderscore" class="external">https://github.com/danielribeiro/RubyUnderscore</a><br>
<a href="https://github.com/raganwald/homoiconic/blob/master/2012/05/anaphora.md" class="external">https://github.com/raganwald/homoiconic/blob/master/2012/05/anaphora.md</a><br>
<a href="https://bugs.ruby-lang.org/issues/8987" class="external">https://bugs.ruby-lang.org/issues/8987</a> (my request)</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=455742014-03-02T16:11:32Zphluid61 (Matthew Kerwin)matthew@kerwin.net.au
<ul></ul><p>I share concerns that have been voiced earlier in the thread.</p>
<p>This code snippet: <code>foo &.bar</code> <em>looks</em> like you're either passing <code>&.bar</code> as the first positional parameter to foo, or casting <code>.bar</code> to a Proc and passing it as the block parameter. You might argue that that <em>is</em> what you're doing, but it's not; <code>.bar</code> isn't a thing that can be #to_proc'd, and <code>&</code> isn't an object you can send method calls. What we end up doing is confusing the syntax, adding a third option which looks like a hybrid of the others, but is something else again.</p>
<p>I think the ampex gem better captures the intent here by both using the <code>&</code> sigil/operator to clearly indicate that Proc->block magic is happening, and by providing an explicit object to receive the method calls. Of course it could never be promoted to core, because the name 'X' is far too valuable and I doubt anyone could come up with a better one, but personally I'm happy enough that the gem exists and can be used by those to whom it would be of benefit.</p>
<p>And if it's too slow for you, write out the full code, even if that means creating a throw-away variable in your block. We like variables, they show us what our code is doing. I doubt it's a goal of the language to remove them.</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=455812014-03-02T22:37:32Zsowieso (So Wieso)sowieso@dukun.de
<ul></ul><p>Matthew Kerwin wrote:</p>
<blockquote>
<p>I share concerns that have been voiced earlier in the thread.</p>
<p>This code snippet: <code>foo &.bar</code> <em>looks</em> like you're either passing <code>&.bar</code> as the first positional parameter to foo, or casting <code>.bar</code> to a Proc and passing it as the block parameter. You might argue that that <em>is</em> what you're doing, but it's not; <code>.bar</code> isn't a thing that can be #to_proc'd, and <code>&</code> isn't an object you can send method calls. What we end up doing is confusing the syntax, adding a third option which looks like a hybrid of the others, but is something else again.</p>
</blockquote>
<p>You are totally right, this is yet another use for &. But if you take the new rule, it is not really confusing, just parse it like explained when you see & followed by a dot. And you still have the & warning you: here is something blockish going on.</p>
<blockquote>
<p>I think the ampex gem better captures the intent here by both using the <code>&</code> sigil/operator to clearly indicate that Proc->block magic is happening, and by providing an explicit object to receive the method calls. Of course it could never be promoted to core, because the name 'X' is far too valuable and I doubt anyone could come up with a better one, but personally I'm happy enough that the gem exists and can be used by those to whom it would be of benefit.</p>
</blockquote>
<p>I agree, X is a no-go. Wouldn't any symbol (in ascii) be possible? (<code>map &@.to_s</code>, or even <code>map @.to_s</code>)</p>
<blockquote>
<p>And if it's too slow for you, write out the full code, even if that means creating a throw-away variable in your block. We like variables, they show us what our code is doing. I doubt it's a goal of the language to remove them.</p>
</blockquote>
<p>I disagree here. The usual one-letter-variables in real code do not show anything. This implementation would still force us to give them a name if we want to use them more than once, which is a compromise on a good level.</p>
<p>What if we do it like this?<br>
<code>[1,2,3,4].map{.to_s(2)}.reverse => ["100", "11", "10", "1"]</code><br>
When there is no receiver for a method-call (can only be the first method-call in a block), send the message to yielded argument.</p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=455842014-03-03T01:01:40Zphluid61 (Matthew Kerwin)matthew@kerwin.net.au
<ul></ul><p>On 3 March 2014 08:37, <a href="mailto:sowieso@dukun.de" class="email">sowieso@dukun.de</a> wrote:</p>
<blockquote>
<p>Issue <a class="issue tracker-2 status-7 priority-4 priority-default closed" title="Feature: New one-argument block syntax: &. (Feedback)" href="https://redmine.ruby-lang.org/issues/9076">#9076</a> has been updated by So Wieso.</p>
<p>Matthew Kerwin wrote:</p>
<blockquote>
<p>I share concerns that have been voiced earlier in the thread.</p>
<p>This code snippet: <code>foo &.bar</code> <em>looks</em> like you're either passing<br>
<code>&.bar</code> as the first positional parameter to foo, or casting <code>.bar</code> to a<br>
Proc and passing it as the block parameter. You might argue that that <em>is</em><br>
what you're doing, but it's not; <code>.bar</code> isn't a thing that can be<br>
#to_proc'd, and <code>&</code> isn't an object you can send method calls. What we end<br>
up doing is confusing the syntax, adding a third option which looks like a<br>
hybrid of the others, but is something else again.</p>
</blockquote>
<p>You are totally right, this is yet another use for &. But if you take the<br>
new rule, it is not really confusing, just parse it like explained when you<br>
see & followed by a dot.</p>
</blockquote>
<p>I think it's pretty confusing, and some of the conversation upthread seems<br>
to agree. I don't like having to carefully read and parse code to see if<br>
it's & or . or &. -- I'm not a computer, I don't read that way.</p>
<blockquote>
<p>I think the ampex gem better captures the intent here by both using the<br>
<code>&</code> sigil/operator to clearly indicate that Proc->block magic is happening,<br>
and by providing an explicit object to receive the method calls. Of course<br>
it could never be promoted to core, because the name 'X' is far too<br>
valuable and I doubt anyone could come up with a better one, but personally<br>
I'm happy enough that the gem exists and can be used by those to whom it<br>
would be of benefit.</p>
<p>I agree, X is a no-go. Wouldn't any symbol (in ascii) be possible? (<code>map &@.to_s</code>, or even <code>map @.to_s</code>)</p>
</blockquote>
<p>It may be possible, but I don't like Perl's sigil-heavy and<br>
magic-variable-creating voodoo, and I'd much prefer Ruby to keep it limited<br>
to what it already has. I think X is perfectly apt for the gem; there's a<br>
very strong convention that 'i' is the index in a loop and 'x' is the item,<br>
so having a globally defined X is sensible, it's just a bit too broad of a<br>
brush for the core.</p>
<p>And @ (and @@) are class scoping sigils, so they're not appropriate here.</p>
<blockquote>
<blockquote>
<p>And if it's too slow for you, write out the full code, even if that<br>
means creating a throw-away variable in your block. We like variables, they<br>
show us what our code is doing. I doubt it's a goal of the language to<br>
remove them.</p>
</blockquote>
<p>I disagree here. The usual one-letter-variables in real code do not show<br>
anything. This implementation would still force us to give them a name if<br>
we want to use them more than once, which is a compromise on a good level.</p>
</blockquote>
<p>They show us several things: precisely where the variable comes from<br>
(again, I can't stand Perl's $_ just appearing -- or worse, changing -- in<br>
random places), precisely where and how it's used, and if it's called "x"<br>
it also strongly suggests that it's the item in an iteration that doesn't<br>
have an particular meaning outside the context of the iteration (unless<br>
we're doing something with coordinates, in which case context should be<br>
enough to inform the difference).</p>
<blockquote>
<p>What if we do it like this?<br>
<code>[1,2,3,4].map{.to_s(2)}.reverse => ["100", "11", "10", "1"]</code><br>
When there is no receiver for a method-call (can only be the first<br>
method-call in a block), send the message to yielded argument.</p>
</blockquote>
<p>I think this has been proposed before. You'd have to clearly enumerate<br>
edge cases (e.g.: <code>def each() yield; yield 1, 2; end</code>), and it still<br>
doesn't look great.</p>
<p>To summarise my opinion: I agree that there's a lot of value in being able<br>
to brain-dump the equivalent of <code>foo.map{|x|x.to_s(2)}</code> without having to<br>
break your train of thought, but I don't think <code>&.</code> is the right way.</p>
<p>--<br>
Matthew Kerwin<br>
<a href="http://matthew.kerwin.net.au/" class="external">http://matthew.kerwin.net.au/</a></p> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=470562014-06-06T05:24:27Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-6 priority-4 priority-default closed" href="/issues/4146">Feature #4146</a>: Improvement of Symbol and Proc</i> added</li></ul> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=470582014-06-06T05:26:46Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/47058/diff?detail_id=33963">diff</a>)</li></ul> Ruby master - Feature #9076: New one-argument block syntax: &.https://redmine.ruby-lang.org/issues/9076?journal_id=891082020-12-10T08:53:41Znaruse (Yui NARUSE)naruse@airemix.jp
<ul><li><strong>Target version</strong> deleted (<del><i>3.0</i></del>)</li></ul>