https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112022-08-26T10:32:21ZRuby Issue Tracking SystemRuby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989332022-08-26T10:32:21Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul><li><strong>Is duplicate of</strong> <i><a class="issue tracker-2 status-5 priority-4 priority-default closed" href="/issues/15897">Feature #15897</a>: `it` as a default block parameter</i> added</li></ul> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989362022-08-26T10:32:28Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-5 priority-4 priority-default closed" href="/issues/4475">Feature #4475</a>: default variable name for parameter</i> added</li></ul> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989382022-08-26T10:32:35Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul><li><strong>Related to</strong> <i><a class="issue tracker-5 status-7 priority-4 priority-default closed" href="/issues/15723">Misc #15723</a>: Reconsider numbered parameters</i> added</li></ul> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989392022-08-26T10:33:34Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/98939/diff?detail_id=63059">diff</a>)</li></ul> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989402022-08-26T10:38:16Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/98940/diff?detail_id=63060">diff</a>)</li></ul> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989412022-08-26T10:44:01Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/98941/diff?detail_id=63061">diff</a>)</li></ul> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989422022-08-26T12:43:21ZEregon (Benoit Daloze)
<ul></ul><p>I regularly use <code>_1</code>, <code>_2</code>, maybe it's question of habit and getting used to it?<br>
<code>_1</code> seems already used in many gems (<code>gem-codesearch '\b_1\b' | grep '\.rb:\s'</code>).<br>
It's also a syntax used in other languages, and <code>_</code> is already established as a "special variable" in Ruby since ages in IRB.</p>
<blockquote>
<p>Numbered parameters (_1, _2, ...) look like unused local variables</p>
</blockquote>
<p>Unused local variables are more like <code>_[a-z]\w+</code>, the number makes the variable "anonymous" so it can't be an unused local variable (also if you remove the leading <code>_</code> it's no longer a variable).</p>
<p>I dislike <code>it</code>, because it looks like a local variable (or method call) and doesn't make it clear it's special syntactic sugar with wider effect than a local variable (i.e., it adds a parameter to the surrounding block).<br>
If <code>it</code> is used in a block it does not stand out, it just looks like any other variable/vcall. OTOH _1/_2 is fairly visible and makes it easy to see how many parameters the block has.</p>
<p>Also <code>it</code> only works for a single argument so it feels inconsistent and incomplete.<br>
There is probably also little chance to syntax highlight <code>it</code> correctly in IDEs/editors as something special, because it wouldn't be a keyword, it's already used as a method (in RSpec/MSpec/etc), and it seems too complicated for most editors to be able to discern which meaning of <code>it</code> it is based on the context (unless a LSP is used maybe, but many editors don't).</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989442022-08-26T14:41:27Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul></ul><blockquote>
<p>I regularly use _1, _2, maybe it's question of habit and getting used to it?</p>
</blockquote>
<p>Matz also made that argument in the Ruby Committers vs the World 2019, saying many people started using <code>-> {}</code> after almost 100% of the people objected to the idea (<a href="https://youtu.be/5eAXAUTtNYU?t=3300" class="external">ref</a>). I wrote this proposal after listening to that, which is why I wrote "I have barely used it in the last 2~3 years" to make a point that I never get used to it.</p>
<blockquote>
<p>It's also a syntax used in other languages</p>
</blockquote>
<p><code>it</code> is too.</p>
<blockquote>
<p>_ is already established as a "special variable" in Ruby since ages in IRB.</p>
</blockquote>
<p>What do you mean? I thought we were talking about <code>_1</code>, not <code>_</code>. If this feature were introduced as <code>_</code>, I would use it much more often than <code>_1</code>, but <a href="https://bugs.ruby-lang.org/issues/15723#note-126" class="external">Matz finds <code>_</code> confusing</a>, and I like <code>it</code> more anyway.</p>
<blockquote>
<p>Also it only works for a single argument so it feels inconsistent and incomplete.</p>
</blockquote>
<p>I'd like to note that I'm not proposing to delete numbered parameters, and I thought it's nice to re-raise this topic because we no longer need to discuss "what about second arguments?" now that we already have <code>_2</code>. You already have a solution to your use case, and I still don't have one.</p>
<p>So, here's the use case I have but you don't seem to share with me. I'm not clever enough to remember the order of parameters. Therefore, when a block has multiple parameters, I'd always want to name those parameters because which is <code>_1</code> or <code>_2</code> is not immediately obvious. Thus I would use this feature only when a block takes a single argument, which is actually pretty common. If I use <code>_1</code>, it feels like there might be a second argument, and you might waste time to think about <code>_2</code>, even if <code>_2</code> doesn't exist, which is a cognitive overhead. If you use <code>it</code>, it kinda implies there's only a single argument, so you don't need to spend time remembering whether <code>_2</code> exists or not. It is important for me that <code>it</code> is <em>"incomplete"</em>.</p>
<blockquote>
<p>There is probably also little chance to syntax highlight it correctly in IDEs/editors as something special, because it wouldn't be a keyword, it's already used as a method (in RSpec/MSpec/etc), and it seems too complicated for most editors to be able to discern which meaning of it it is based on the context (unless a LSP is used maybe, but many editors don't).</p>
</blockquote>
<p>Kotlin's <code>it</code> doesn't really stand out like a keyword on IntelliJ (it's bold white, not really different from non-bold while method calls or variables) compared to other yellow ones, but I never felt it's a problem because <code>it</code> is typically used when it's a one liner and what <code>it</code> means is obvious without fancy highlighting.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989472022-08-26T15:45:57ZEregon (Benoit Daloze)
<ul></ul><p>k0kubun (Takashi Kokubun) wrote in <a href="#note-8">#note-8</a>:</p>
<blockquote>
<p>What do you mean? I thought we were talking about <code>_1</code>, not <code>_</code>. If this feature were introduced as <code>_</code>, I would use it much more often than <code>_1</code>, but <a href="https://bugs.ruby-lang.org/issues/15723#note-126" class="external">Matz finds <code>_</code> confusing</a>, and I like <code>it</code> more anyway.</p>
</blockquote>
<p>I just think <code>_</code>, <code>_1</code> and <code>_foo</code> are related, they are all "special local variables".<br>
The first one is "last result in IRB", the second is "numbered parameters" and the third is "unused variable".<br>
So I find it consistent that numbered paramters uses one of these "special local variables".</p>
<blockquote>
<p>So, here's the use case I have but you don't seem to share with me. I'm not clever enough to remember the order of parameters. Therefore, when a block has multiple parameters, I'd always want to name those parameters because which is <code>_1</code> or <code>_2</code> is not immediately obvious. Thus I would use this feature only when a block takes a single argument, which is actually pretty common. If I use <code>_1</code>, it feels like there might be a second argument, and you might waste time to think about <code>_2</code>, even if <code>_2</code> doesn't exist, which is a cognitive overhead. If you use <code>it</code>, it kinda implies there's only a single argument, so you don't need to spend time remembering whether <code>_2</code> exists or not. It is important for me that <code>it</code> is <em>"incomplete"</em>.</p>
</blockquote>
<p>This is a good argument, I think it would be good to add to the issue description.</p>
<p>I agree if e.g. <code>_1</code> and <code>_2</code> are far apart or the block is long it hurts readability, and IMHO one should use named parameters instead for long blocks or if arguments are used far apart.<br>
A typical case I use _1 and _2 would be <code>hash.each_pair { p [_1, _2] }</code> or so, where the block is very small and the overhead to see if there is a <code>_2</code> seems very low.<br>
I think also in most cases the method which is given the block should be clear how many arguments it passes to the block, and the in the majority of cases it's a single one.</p>
<blockquote>
<p>Kotlin's <code>it</code> doesn't really stand out like a keyword on IntelliJ (it's bold white, not really different from non-bold while method calls or variables) compared to other yellow ones, but I never felt it's a problem because <code>it</code> is typically used when it's a one liner and what <code>it</code> means is obvious without fancy highlighting.</p>
</blockquote>
<p>My worry with that is then it's even harder to notice than <code>_1</code>/<code>_2</code>/etc and so it's unclear if the block takes 0 or 1 argument, one need to look for a innocuous word (<code>it</code>) in the middle of the rest the expression, which is typically a bunch of other words (method calls & variables).<br>
I think it's a bit like string interpolation, that's visible thanks to the sigils and syntax highlighting. If it was a word instead of <code>#{}</code> it would be a total nightmare.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989482022-08-26T15:48:51ZEregon (Benoit Daloze)
<ul></ul><blockquote>
<p>innocuous word</p>
</blockquote>
<p>I misused <code>innocuous</code> here. I want to mean a "common word", and it's hard to notice because it's the same syntax as a local variable or method call.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989552022-08-26T21:38:09Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/98955/diff?detail_id=63062">diff</a>)</li></ul> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989562022-08-26T22:46:32Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul></ul><blockquote>
<p>This is a good argument, I think it would be good to add to the issue description.</p>
</blockquote>
<p>I'm glad it made sense to you. Sure, I updated the issue description to include that.</p>
<blockquote>
<p>There is probably also little chance to syntax highlight it correctly in IDEs/editors as something special, because<br>
it's already used as a method (in RSpec/MSpec/etc)</p>
</blockquote>
<p>I'm not sure if it's too difficult to distinguish "a method (in RSpec/MSpec/etc)" taking arguments from <code>it</code> without an argument. Even if you don't have an AST, a peek of the next token (<code>it "returns xxx"</code> or <code>it { is_expected xxx }</code> vs <code>it.xxx</code> or <code>xxx(it)</code>) would give you a fairly reliable guess.</p>
<blockquote>
<p>it wouldn't be a keyword</p>
</blockquote>
<p>I don't think this is a blocker. For example, while <code>require</code> is not a keyword, my VSCode highlights it as if it's a keyword. It seems to just match the text in an identifier instead of checking whether it's an actual Ruby keyword or not. So highlighting <code>it</code> as "special local variables" seems feasible.</p>
<blockquote>
<p>it seems too complicated for most editors to be able to discern which meaning of it it is based on the context (unless a LSP is used maybe, but many editors don't).</p>
</blockquote>
<p>Note that this general problem is not specific to <code>it</code>. Bringing up the <code>require</code> example again, let's say your method have a keyword argument <code>require: false</code>, my VSCode highlights the argument as if it's a <code>require</code> method. But it doesn't make you think "let's not introduce <code>require</code> unless it becomes a keyword!", right? We use basic text matching and can live with it.</p>
<blockquote>
<p>My worry with that is then it's even harder to notice than <code>_1</code>/<code>_2</code>/etc and so it's unclear if the block takes 0 or 1 argument</p>
</blockquote>
<p>So my suggestion to this problem is to use the same color as "special local variables" when an identifier not taking arguments is named <code>it</code>. This could of course highlight a local variable <code>it</code> as if it's <code>_1</code>, but as I discussed in the "Confusion" section, a non-meaningful variable name <code>it</code> would be used when you can easily figure out the meaning of <code>it</code>, because otherwise you'd give a meaningful name to it to make it understandable. So you should typically be able to understand it's a local variable <code>it</code> even with the imperfect syntax highlight.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989572022-08-26T23:32:34Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul></ul><p>If we are considering an alternative to <code>_1</code>, I'm going to vote again for <code>@</code> (bare at sign) (originally proposed in <a href="https://bugs.ruby-lang.org/issues/4475#note-10" class="external">https://bugs.ruby-lang.org/issues/4475#note-10</a>). This is currently invalid syntax, so there is no possibility of backwards compatibility issues when using it. I think it would also do a better job of standing out than <code>it</code>, which appears to be a normal local variable.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989642022-08-27T09:04:08Zhanazuki (Kasumi Hanazuki)
<ul></ul><p>I also avoid using solo <code>_1</code> as I have to search for <code>_2</code> when I see <code>_1</code> in a block. It's not because of a feeling caused by the number but because the behavior of <code>_1</code> changes depending on the occurrence of <code>_2</code>.</p>
<p>Given that we have a block that takes a single argument, when only <code>_1</code> is used in the block, <code>_1</code> refers to the argument itself. Otherwise, <code>_1</code> is bound to the first element of the argument.<br>
That is:</p>
<ul>
<li>proc { _1 }.call([1, 2]) #=> [1, 2]</li>
<li>proc { _2; _1 }.call([1, 2]) #=> 1</li>
</ul>
<p>So when you encounter <code>_1</code> in a code, you always have to scan the entire block (though it should be short) to see if <code>_2</code> occurs to determine how <code>_1</code> works. (This problem has been discussed in <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Numbered parameters: _1 should be the same as |x| and _0 should not exist (Closed)" href="https://bugs.ruby-lang.org/issues/16178">#16178</a>)</p>
<p>Syntax that requires this kind of arbitrary lookahead to understand is rare in Ruby, so I hesitate to use it in order to keep my code simple. But blocks like<code>{|x| x.something(...) }</code> and <code>{|y| something(y) }</code> are actually common, and I hope Ruby to have a variant of <code>_1</code> that is always bound to the first argument (not its first element).</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989842022-08-28T16:42:18Zgraywolf (Gray Wolf)
<ul></ul><p>jeremyevans0 (Jeremy Evans) wrote in <a href="#note-13">#note-13</a>:</p>
<blockquote>
<p>If we are considering an alternative to <code>_1</code>, I'm going to vote again for <code>@</code> (bare at sign) (originally proposed in <a href="https://bugs.ruby-lang.org/issues/4475#note-10" class="external">https://bugs.ruby-lang.org/issues/4475#note-10</a>). This is currently invalid syntax, so there is no possibility of backwards compatibility issues when using it. I think it would also do a better job of standing out than <code>it</code>, which appears to be a normal local variable.</p>
</blockquote>
<p>This sounds like a good idea. Fully backwards compatible, stands out and easy to highlight (since that seems to be relevant based on the debate here).</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989852022-08-28T20:42:28Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul></ul><p>For your information, <code>@</code> was a candidate discussed and rejected when <code>@1</code> was changed to <code>_1</code>. I'm raising <code>it</code> partly because it hasn't been explicitly rejected. However, for the same reason discussed above, <code>@</code> is still a better compromise for me than <code>_1</code> if we choose not to introduce <code>it</code>.</p>
<blockquote>
<p><a href="https://docs.google.com/document/d/1XypDO1crRV9uNg1_ajxkljVdN8Vdyl5hnz462bDQw34/edit#heading=h.s5b1eox1ywa3" class="external">https://docs.google.com/document/d/1XypDO1crRV9uNg1_ajxkljVdN8Vdyl5hnz462bDQw34/edit#heading=h.s5b1eox1ywa3</a></p>
</blockquote> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989862022-08-28T21:21:50Zbaweaver (Brandon Weaver)keystonelemur@gmail.com
<ul></ul><a name="Aliasing"></a>
<h4 >Aliasing<a href="#Aliasing" class="wiki-anchor">¶</a></h4>
<p>While I understand that <code>_1</code> is not necessarily clear and immediately obvious it has seen a lot of use. Even if we were to introduce <code>it</code> or any other syntax it would effectively be an alias so as to not break compatibility.</p>
<p>If that were the case then the benefit gained from introducing <code>it</code> would mostly be in having another way to express the same idea, albeit clearer in meaning potentially.</p>
<h4>
<code>@1</code> syntax</h4>
<p>I do not see a distinct enough difference to justify <code>@1</code>, and would reiterate previous arguments that even if it is technically illegal syntax it will still be confused for instance variables, which presents more problems than <code>_1</code> which is assumed to be local.</p>
<a name="2-Args"></a>
<h4 >2+ Args<a href="#2-Args" class="wiki-anchor">¶</a></h4>
<p>The problem I have with <code>it</code> is how we express more than one argument. Blocks accept the full range of <code>-> (pos_req, pos_opt = 1, *rest, key_req:, key_opt: 1, **key_rest, &block)</code> so dealing with all of those as a singular splatted <code>it</code> (guessing implied <code>-> *it { it }</code>) seems to be less flexible.</p>
<p>How would you propose we deal with such cases?</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989872022-08-28T21:35:13Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul></ul><blockquote>
<p>@1 syntax</p>
</blockquote>
<p>In case it wasn't clear, the alternative that <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/1604">@jeremyevans0 (Jeremy Evans)</a>, <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/12262">@graywolf (Gray Wolf)</a>, and I talked about was not <code>@1</code> but <code>@</code>. They're different.</p>
<blockquote>
<p>How would you propose we deal with such cases?</p>
</blockquote>
<p>I discussed that at <a href="https://bugs.ruby-lang.org/issues/18980#note-8" class="external">https://bugs.ruby-lang.org/issues/18980#note-8</a>.</p>
<p>2+ args cases are already solved thanks to <code>_1</code> and <code>_2</code>. You already have a solution to that use case and I don't think we need every other feature to support that.</p>
<p>Instead, I want to have an expression to say "this block has only a single parameter so I'm gonna use <code>it</code>" because <code>_1</code> implies <code>_2</code> possibly exists, which is a cognitive overhead when reading the code.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989882022-08-28T21:37:55Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul></ul><p>baweaver (Brandon Weaver) wrote in <a href="#note-17">#note-17</a>:</p>
<blockquote>
<p>I do not see a distinct enough difference to justify <code>@1</code>, and would reiterate previous arguments that even if it is technically illegal syntax it will still be confused for instance variables, which presents more problems than <code>_1</code> which is assumed to be local.</p>
</blockquote>
<p>To be clear, I am proposing just <code>@</code> as an alias for <code>_1</code> (as an alternative to <code>it</code>). I'm not proposing <code>@1</code>, <code>@2</code>, etc.. We already have <code>_1</code>, <code>_2</code>, etc and I believe this proposal is not to deprecate the current numbered parameters support, but merely offer a more readable alias for <code>_1</code>.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989902022-08-29T08:05:59Zzverok (Victor Shepelev)zverok.offline@gmail.com
<ul></ul><p>My 5c: I came to (almost) peace with <code>_1</code>, and we use it extensively in the codebase, and find it quite convenient.</p>
<p>Choosing the designation for it is a hard choice, and after years of consideration, I believe that the current solution, if looking somewhat "weird", is a very well-balanced choice, and I still didn' see any that is better.</p>
<p>From my PoV, the design space can be described this way:</p>
<ol>
<li>It should be something following the rules of scoping by its name (e.g. <code>_1</code> is a valid name of local variable, implying locality). This rules out <code>@1</code>, which implies "some special <em>instance</em> variable"</li>
<li>It should look <em>special</em>. Even if you don't know its meaning (just learning Ruby, or haven't upgraded your knowledge of the language for a long time), it should immediately imply "it is not just a regular name like all other names". This rules out <code>it</code>. Even besides "somebody could've used this name already" (and somebody could indeed, besides RSpec, I saw codebases which used this abbreviation to mean "iterator", "item", or "i(ndex of) t(ime point)"), it just doesn't give a strong feeling of "this is a local name, but also a special name".</li>
<li>As far as I understand, we are currently quite reluctant towards introducing "Perlisms" like "this character means something new in that context." For operators (verbs) we seek to recombine existing ones (like <code>in</code> and <code>=></code> for pattern matching), and for variables/methods, we seek to stay with existing naming schemes.</li>
<li>(Have mixed feelings about this one) It probably should allow a sequence of similar names (like <code>_1</code>/<code>_2</code> do)</li>
</ol>
<p>TBH, I can't think of much better naming scheme which would satisfy <em>at least</em> 1-3.</p>
<p>About 4: like <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/10073">@k0kubun (Takashi Kokubun)</a>, I find myself not very comfortable with <code>_1</code> meaning different things depending on the presence of <code>_2</code>. As a consequence, I use <code>_1</code> extensively in obvious cases (when it is the <em>only</em> one), but while iterating on hashes, I frequently prefer to name the block params explicitly.</p>
<p>That actually might be a greater obstacle for adoption (at least for some) than particular naming, which also highlighted by <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/10073">@k0kubun (Takashi Kokubun)</a> in the "Why I don't use _1" section.</p>
<p>In our current codebase (quite large), that switched to Ruby 2.7 a year ago, there are ~200 entries of <code>_1</code>, and 6 (six) usages of <code>_2</code> (and no usages of <code>_3</code>, <code>_4</code> etc.).<br>
And while <code>_1</code> is used extensively and really helps to write shorter and DRYer blocks, our usages of <code>_2</code> are mostly "clever-isms" like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">users</span><span class="p">.</span><span class="nf">sort</span> <span class="p">{</span> <span class="n">_2</span><span class="p">.</span><span class="nf">last_seen_at</span> <span class="o"><=></span> <span class="n">_1</span><span class="p">.</span><span class="nf">last_seen_at</span> <span class="p">}</span>
<span class="c1"># the "clever" way of doing just...</span>
<span class="n">users</span><span class="p">.</span><span class="nf">sort_by</span><span class="p">(</span><span class="o">&</span><span class="ss">:last_seen_at</span><span class="p">).</span><span class="nf">reverse</span>
<span class="c1"># ...because we still don't have `reverse_sort_by`</span>
</code></pre>
<p>So, the thinking-out-of-the-box solution might be to preserve <code>_1</code>, but deprecate the rest :)</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=989982022-08-29T11:03:38ZEregon (Benoit Daloze)
<ul></ul><p>The logical sigil for a single arguments would be <code>_</code> of course (given we have <code>_1</code>, <code>_2</code>, etc).<br>
I forgot, is <code>_</code> problematic in practice?</p>
<p>The usage of it in irb/pry should not be an issue given the variable is explicitly declared there I'd imagine.<br>
So for cases where it's already a local variable then it just reads that local variable instead of being a numbered parameter.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990022022-08-29T11:53:25Zzverok (Victor Shepelev)zverok.offline@gmail.com
<ul></ul><blockquote>
<p>I forgot, is _ problematic in practice?</p>
</blockquote>
<p><code>_</code> is very widespread name to "I don't need that". TBH, till 5 min ago I thought it is processed specially in the case of parameter repetition:</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="p">[</span><span class="mi">4</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="p">{</span> <span class="o">|</span><span class="n">i</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="o">|</span> <span class="n">i</span> <span class="p">}</span> <span class="c1"># => works</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="p">[</span><span class="mi">4</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="p">{</span> <span class="o">|</span><span class="n">i</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">x</span><span class="o">|</span> <span class="n">i</span> <span class="p">}</span> <span class="c1">#duplicated argument name</span>
<span class="c1"># ..., 3], [4, 5, 6]].map { |i, x, x| i }</span>
<span class="c1"># ... ^</span>
</code></pre>
<p>But actually, to my surprise, this works too (anything starting with <code>_</code>):</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="p">[</span><span class="mi">4</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="p">{</span> <span class="o">|</span><span class="n">i</span><span class="p">,</span> <span class="n">_x</span><span class="p">,</span> <span class="n">_x</span><span class="o">|</span> <span class="n">i</span> <span class="p">}</span> <span class="c1"># => works</span>
</code></pre>
<p>Anyway, <code>_</code> has a strong association with "drop that".<br>
One might argue that <code>_1</code> does, too, but I think it looks differently (and, well, it is two years already, I know a lot of people who have their brain rewired to distinguish <code>_1</code>)</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990132022-08-29T23:37:40Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul></ul><blockquote>
<p>Unused local variables are more like <code>_[a-z]\w+</code>, the number makes the variable "anonymous" so it can't be an unused local variable</p>
<p>Anyway, <code>_</code> has a strong association with "drop that". One might argue that <code>_1</code> does, too, but I think it looks differently</p>
</blockquote>
<p>It's interesting that "Numbered parameters (<code>_1</code>, <code>_2</code>, ...) look like unused local variables" doesn't seem to resonate with you. To me, <code>_1</code> looks almost exactly like <code>_l</code>, which is, did you notice, an unused local variable.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990182022-08-30T07:07:07Zzverok (Victor Shepelev)zverok.offline@gmail.com
<ul></ul><blockquote>
<p>It's interesting that "Numbered parameters (_1, _2, ...) look like unused local variables" doesn't seem to resonate with you.</p>
</blockquote>
<p>It did initially, but let's say I got over it. There were several factors in play:</p>
<ol>
<li>I am very concerned about readability and brevity, but I actually don't believe <em>any</em> "core" name choice makes something "totally unreadable". Syntax structures might, but names are just sigils you soon get used too. Say, I considered <code>yield_self</code> so wrong naming choice I spent the good part of that year fighting for its renaming, but at the same time I started to use it (and it DID make code better, as my colleagues agreed, you just needed to get used to the weird name). I frequently call for name compromises (let's stop on <em>one</em> name and move forward instead of five more years of discussion).</li>
<li>At the moment of introduction of numbered args, I was more concerned that it is a <em>principally</em> wrong feature (it somewhat overshadowed the idea of shortening blocks with method references, with method references then being dropped altogether). But then I tried it reluctantly and turned out it made life much easier.</li>
<li>In practice, it was really easy to get used to. <code>_1</code> is easy to remember and recognize in others' code. And I never met code that uses <code>_1</code> before (and rarely the code that uses <code>_l</code>, TBH), so it wasn't like I really needed to rewire my mind to stop recognizing it as "unused variable."</li>
<li>I did the "design space analysis" <a href="https://bugs.ruby-lang.org/issues/18980#note-20" class="external">from above</a> at feature introduction, and I still believe that while <code>_1</code> looks weird(ish) for those not used to it, it is a reasonable choice. At least in my book, it is arguably better than <code>@1</code> (associates with non-local name), <code>it</code> (looks like a "regular" name, not a distinguished special thing), or <code>_</code> (this one is <em>really</em> used as an "unused argument" regularly).</li>
</ol>
<p>So... yeah.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990212022-08-30T08:25:41Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul></ul><blockquote>
<p>Say, I considered <code>yield_self</code> so wrong naming choice I spent the good part of that year fighting for its renaming, but at the same time I started to use it (and it DID make code better, as my colleagues agreed, you just needed to get used to the weird name).</p>
</blockquote>
<p>Haha, I rarely used <code>yield_self</code> because it looked like a compromised name, and <em>then</em> I liked and used it so much when <code>then</code> was added. It's a nice analogy.</p>
<blockquote>
<p>(let's stop on one name and move forward instead of five more years of discussion)</p>
</blockquote>
<p>As a Rubyist who was born in the same year as Ruby and could use Ruby for tens of more years, possibly longer than Matz, experimenting with <code>_1</code> for 3 years and discussing it again to fix compromises feels like a good use of our time TBH.</p>
<blockquote>
<p>I frequently call for name compromises<br>
I still believe that while _1 looks weird(ish) for those not used to it</p>
</blockquote>
<p>The general idea of numbered parameters supporters in this ticket seems to be "you'll get used to it". Let's forget the fact that I didn't get used to it after 3 years, if you were able to design Ruby from the ground up, would you still use a syntax that you think is a name compromise and looks weird for newcomers? I wouldn't, and that thinking leads me to pick <code>it</code> for this feature.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990242022-08-30T11:27:26Zzverok (Victor Shepelev)zverok.offline@gmail.com
<ul></ul><blockquote>
<p>if you were able to design Ruby from the ground up, would you still use a syntax that you think is a name compromise and looks weird for newcomers?</p>
</blockquote>
<p>My "design space analysis" was sourced by the same idea. I can say that I would NOT choose <code>it</code> (or any other name looking "regularly"), unless it would be a keyword (like <code>self</code>), having exactly one meaning always, but even then— I am not sure.</p>
<p>I'd say that in this case, I would like <code>_1</code> even more: it still keeps the balance between "looks special" and "corresponds to the rules for local names, so it is visible it is local" + allows to define several consequential variables; but, be it in the language from the beginning, it wouldn't have a sour feeling "but before, underscore meant 'drop this var'!"</p>
<p>I'd actually say that it is less confusing for newcomers than for seasoned Rubyists; I regularly observe younger colleagues being introduced to the notion and getting used to it in a blink of an eye.</p>
<p>In hindsight, I am sadder that <code>_0</code> was dropped (to mean "all args unsplatted" and distinguish from <code>_1</code> which would always be "first of args, splatted").</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990262022-08-30T13:38:16Zufuk (Ufuk Kayserilioglu)
<ul></ul><p>zverok (Victor Shepelev) wrote in <a href="#note-26">#note-26</a>:</p>
<blockquote>
<p>My "design space analysis" was sourced by the same idea. I can say that I would NOT choose <code>it</code> (or any other name looking "regularly"), unless it would be a keyword (like <code>self</code>), having exactly one meaning always, but even then— I am not sure.</p>
</blockquote>
<p>One thing that this "design space analysis" keeps ignoring, though, is the proposal by <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/1604">@jeremyevans0 (Jeremy Evans)</a> to use a bare <code>@</code> as a synonym for <code>_1</code>, as in:</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="nf">each</span> <span class="p">{</span> <span class="nb">puts</span> <span class="err">@</span> <span class="p">}</span>
</code></pre>
<p>which (you can see from the syntax highlighting above) is currently a syntax error.</p>
<p>While, I, personally, don't like the line noise introduced by yet another sigil, I do understand the concern that <code>_1</code> cognitively implies <code>_2</code>, <code>_3</code>, etc, and special syntax for the single argument case would be better for code readability overall. I have no concerns with using <code>it</code>, since "it" will hardly have many compatibility problems if implemented in the way <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/10073">@k0kubun (Takashi Kokubun)</a> is suggesting. However, if <code>it</code> is deemed not suitable, then I think <code>@</code> is a good fallback.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990272022-08-30T14:16:01Zzverok (Victor Shepelev)zverok.offline@gmail.com
<ul></ul><blockquote>
<p>One thing that this "design space analysis" keeps ignoring, ...</p>
</blockquote>
<p>It doesn't (though I by no means consider it exhaustive or definitive, it is just "what I am thinking about when considering options"):</p>
<blockquote>
<p>As far as I understand, we are currently quite reluctant towards introducing "Perlisms" like "this character means something new in that context." For operators (verbs) we seek to recombine existing ones (like <code>in</code> and <code>=></code> for pattern matching), and for variables/methods, we seek to stay with existing naming schemes.</p>
</blockquote>
<p>It doesn't mention <code>@</code> directly, but it covers this proposal.</p>
<p>(One additional consideration is that <code>@.size</code> and <code>@size</code> would be both valid, easy to mistype/misread, and mean completely different things, and as far as I understand, Matz tries to avoid such situations.)</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990412022-08-31T19:36:05ZDan0042 (Daniel DeLorme)
<ul></ul><p>I'm also one of those who didn't manage to get used to this syntax. I'll use it sometimes in IRB, or in code samples in this tracker, but never in any code I commit... it just feels unclean for some reason.</p>
<p>So far I count k0kubun and hanazuki who have similar thoughts. Not sure about Jeremy. It would be very informative to know who else wasn't able to get used to the numbered parameters syntax in those 2~3 years.</p>
<p>Everyone has their favorite alternative though, so while k0kubun prefers <code>it</code> and Jeremy prefers <code>@</code>, I'm still a superfan of <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Omitted block argument if block starts with dot-method call (Rejected)" href="https://bugs.ruby-lang.org/issues/16120">#16120</a> Omitted block argument. Some things are hard to let go of.</p>
<p>zverok (Victor Shepelev) wrote in <a href="#note-20">#note-20</a>:</p>
<blockquote>
<p>In our current codebase (quite large), that switched to Ruby 2.7 a year ago, there are ~200 entries of <code>_1</code></p>
</blockquote>
<p>Out of curiosity, how many of those ~200 are used as the first token in the block (like <code>{ _1.foo }</code>) vs. how many used in another way?</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990432022-08-31T20:53:30Zaustin (Austin Ziegler)halostatue@gmail.com
<ul></ul><p>Dan0042 (Daniel DeLorme) wrote in <a href="#note-29">#note-29</a>:</p>
<blockquote>
<p>I'm also one of those who didn't manage to get used to this syntax. I'll use it sometimes in IRB, or in code samples in this tracker, but never in any code I commit... it just feels unclean for some reason.</p>
</blockquote>
<p>I haven’t used it, but that’s because I’m still maintaining libraries that support versions of Ruby that are currently EOL, and I can’t really change that without bumping the major version…</p>
<p>Even in a library that I’m prepping for release, I can’t use some conveniences like <code>foo(...)</code> because <code>jruby</code> doesn’t yet support it (at least in the version I get with Github Actions).</p>
<p>As far as "not liking it", I would have preferred Jeremy’s suggestions <code>@</code>, <code>@1</code>, <code>@2</code>, etc. over <code>_1</code>, <code>_2</code>, but having used them a few times…they’re OK. I do most of my software development in Elixir, JS, or Typescript these days (Ruby is my fallback, but is only about 20% of our production apps, and none of them Rails—instead, Roda). Elixir’s closest case is on anonymous capture functions, <code>& &1</code> (the identity closure—the first <code>&</code> introduces the closure, the second <code>&1</code> is for the parameters). Unlike Ruby, you can’t use <code>&2</code> without using <code>&1</code> somewhere in the anonymous capture function (where you could do <code>_2</code> without using <code>_1</code>).</p>
<p>I’m not a fan of <code>it</code>, and would probably use <code>_1</code> over <code>it</code> most times I reached for something like that.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990452022-08-31T22:04:16Zzverok (Victor Shepelev)zverok.offline@gmail.com
<ul></ul><p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/11019">@Dan0042 (Daniel DeLorme)</a></p>
<blockquote>
<p>Out of curiosity, how many of those ~200 are used as the first token in the block (like { _1.foo }) vs. how many used in another way?</p>
</blockquote>
<p>I am afraid I don't see a pattern that you hope to see (e.g., quoting <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Omitted block argument if block starts with dot-method call (Rejected)" href="https://bugs.ruby-lang.org/issues/16120">#16120</a>, that it would mostly be <code>{ _1.something(args) }</code>.<br>
Here are some:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">.</span><span class="nf">tap</span> <span class="p">{</span> <span class="n">_1</span> <span class="o"><<</span> <span class="ss">:date</span> <span class="k">if</span> <span class="n">time_zone</span><span class="p">.</span><span class="nf">present?</span> <span class="p">}</span>
<span class="p">,</span> <span class="ss">format_with: </span><span class="o">-></span> <span class="p">{</span> <span class="n">_1</span> <span class="o">==</span> <span class="no">UserOrganization</span><span class="o">::</span><span class="no">Active</span> <span class="p">}</span>
<span class="p">.</span><span class="nf">then</span> <span class="p">{</span> <span class="n">disabled</span> <span class="p">?</span> <span class="n">_1</span> <span class="p">:</span> <span class="n">_1</span><span class="p">.</span><span class="nf">reject</span><span class="p">(</span><span class="o">&</span><span class="ss">:disabled?</span><span class="p">)</span> <span class="p">}</span>
<span class="p">.</span><span class="nf">find</span><span class="p">{</span> <span class="n">_1</span><span class="p">[</span><span class="s1">'error'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'task_comment_limit'</span> <span class="p">}</span>
<span class="p">.</span><span class="nf">map</span> <span class="p">{</span> <span class="p">{</span><span class="ss">id: </span><span class="n">_1</span><span class="p">.</span><span class="nf">id</span><span class="p">,</span> <span class="ss">text: </span><span class="n">_1</span><span class="p">.</span><span class="nf">name</span><span class="p">}</span> <span class="p">}.</span><span class="nf">sort_by</span> <span class="p">{</span> <span class="n">_1</span><span class="p">[</span><span class="ss">:text</span><span class="p">]</span> <span class="p">}</span>
<span class="p">.</span><span class="nf">to_h</span> <span class="p">{</span> <span class="p">[</span><span class="n">_1</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">pluralize</span><span class="p">.</span><span class="nf">to_sym</span><span class="p">,</span> <span class="p">[</span><span class="n">activity</span><span class="p">[</span><span class="n">_1</span><span class="p">]]]</span> <span class="p">}</span>
<span class="p">.</span><span class="nf">map</span> <span class="p">{</span> <span class="n">preprocess_row</span><span class="p">(</span><span class="n">_1</span><span class="p">.</span><span class="nf">symbolize_keys</span><span class="p">)</span> <span class="p">}</span>
</code></pre>
<p>(I have tons of those, it is not that I've spent a lot of time choosing, it is just a quick selection from <code>grep _1 {app,lib} -r</code> results)</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990462022-08-31T22:38:51Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul></ul><p>Now I'm almost giving <code>it</code> up because there are more people who dislike <code>it</code> than I expected. I thought compatibility was the only blocker of <code>it</code>, but it doesn't seem like the case.</p>
<p>However, even if <code>it</code> is not gonna make it, the problem will still remain in Ruby:</p>
<blockquote>
<p>Why I don't use <code>_1</code></p>
<p>I'm not clever enough to remember the order of parameters. Therefore, when a block has multiple parameters, I'd always want to name those parameters because which is <code>_1</code> or <code>_2</code> is not immediately obvious. Thus I would use this feature only when a block takes a single argument, which is actually pretty common.</p>
<p>If I use <code>_1</code>, it feels like there might be a second argument, and you might waste time to think about <code>_2</code>, even if <code>_2</code> doesn't exist, which is a cognitive overhead. If you use it, it kinda implies there's only a single argument, so you don't need to spend time remembering whether <code>_2</code> exists or not. It is important for me that there's no number in <code>it</code>.</p>
</blockquote>
<p>I still want some new syntax to do the same thing as <code>_1</code> without saying <code>1</code> because it feels like there's a 2nd parameter, even if I want to say there's no such thing. Looking at <a href="#note-9">#note-9</a> and <a href="#note-20">#note-20</a>, it seems like even people using <code>_1</code> agree that it's a valid problem.</p>
<p>Can we at least agree that there should be a way to do <code>_1</code> without saying <code>1</code>? Would you rather prefer having only a single way to write it?</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990472022-09-01T00:16:07Zbyroot (Jean Boussier)byroot@ruby-lang.org
<ul></ul><blockquote>
<p>Now I'm almost giving it up because there are more people who dislike it than I expected.</p>
</blockquote>
<p>Is it really a problem though? This proposal is basically about a new alias for an existing feature. I don't think it logically need to please everyone given that the feature is already accessible by another syntax. It costs nothing not to use it, so it seems to me that the bar should be whether it's helping a sizeable enough portion of the user base (which is super subjective, but still).</p>
<p>And I for one am very much in favor of <code>it</code> as an alias for <code>_1</code>, I just didn't think I had anything to add to this discussion until now, since I was basically in total agreement with your proposal.</p>
<p>I also want to concur with your numbering argument, I never got used to <code>_1</code> because referencing arguments by position rather than name is a regression to me, it brings me back to function arguments in shell scripts. I'm quite sure I haven't used it a single time since it was introduced, not even for quick IRB experiments.</p>
<p>Given that the vast majority of block out there either take 1 or 0 arguments, having a more pleasant and meaningful alias for that overwhelming majority of cases seem perfectly sensible to me.</p>
<p>As for the proposed alternatives, my subjective stance on them are:</p>
<ul>
<li>Bare <code>@</code> screams "INSTANCE VARIABLE" at my brain, I doubt I'd ever get used to it. And there's also the typo inducing <code>@.size</code> vs <code>@size</code> mentioned previously.</li>
<li>
<code>_</code> I like it less than <code>it</code> but I'm ok with. I don't think its current usage as "ignored argument" really conflict, because if you use it, well, it's obviously used.</li>
</ul> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990502022-09-01T12:23:16ZDan0042 (Daniel DeLorme)
<ul></ul><p>zverok (Victor Shepelev) wrote in <a href="#note-31">#note-31</a>:</p>
<blockquote>
<p>I am afraid I don't see a pattern that you hope to see (e.g., quoting <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Omitted block argument if block starts with dot-method call (Rejected)" href="https://bugs.ruby-lang.org/issues/16120">#16120</a>, that it would mostly be <code>{ _1.something(args) }</code>.</p>
</blockquote>
<p>Thank you. It's surprising to me, but very enlightening. Nothing beats actual data about live usage. Although I would really <em>love</em> to see actual counts, e.g.</p>
<pre><code>egrep _1 | wc -l
egrep '\{ *_1' | wc -l
egrep '\{ *_1\.' | wc -l
</code></pre> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990512022-09-01T13:13:41Zzverok (Victor Shepelev)zverok.offline@gmail.com
<ul></ul><p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/11019">@Dan0042 (Daniel DeLorme)</a></p>
<pre><code>$ egrep _1 {app,lib} -r --include \*.rb | wc -l
378
$ egrep '\{ *_1' {app,lib} -r --include \*.rb | wc -l
151
$ egrep '\{ *_1\.' {app,lib} -r --include \*.rb | wc -l
92
</code></pre>
<p>And even of those 92, not all are suitable for <code>{ .method(args) }</code> syntax, there are some like...</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">.</span><span class="nf">all?</span> <span class="p">{</span> <span class="n">_1</span><span class="p">.</span><span class="nf">data</span><span class="p">.</span><span class="nf">dig</span><span class="p">(</span><span class="n">_1</span><span class="p">.</span><span class="nf">widget_id</span><span class="p">.</span><span class="nf">to_sym</span><span class="p">,</span> <span class="ss">:score</span><span class="p">).</span><span class="nf">nil?</span> <span class="p">}</span>
<span class="p">.</span><span class="nf">then</span> <span class="p">{</span> <span class="n">_1</span><span class="p">.</span><span class="nf">start_with?</span><span class="p">(</span><span class="sr">%r{^(https|http)://?}</span><span class="p">)</span> <span class="p">?</span> <span class="n">_1</span> <span class="p">:</span> <span class="n">_1</span><span class="p">.</span><span class="nf">prepend</span><span class="p">(</span><span class="s1">'https://'</span><span class="p">)</span> <span class="p">}</span>
<span class="p">.</span><span class="nf">each</span> <span class="p">{</span> <span class="n">_1</span><span class="p">.</span><span class="nf">update!</span><span class="p">(</span><span class="ss">allowed_hours: </span><span class="n">weekly_limit</span><span class="p">)</span> <span class="k">unless</span> <span class="n">_1</span><span class="p">.</span><span class="nf">start_date</span> <span class="o">==</span> <span class="n">date</span> <span class="p">}</span>
<span class="p">.</span><span class="nf">filter_map</span> <span class="p">{</span> <span class="n">_1</span><span class="p">.</span><span class="nf">id</span> <span class="k">if</span> <span class="n">_1</span><span class="p">.</span><span class="nf">has_virtual_jobs?</span> <span class="p">}</span>
</code></pre>
<p>etc</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=990522022-09-01T13:57:39ZDan0042 (Daniel DeLorme)
<ul></ul><p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/710">@zverok (Victor Shepelev)</a> Again, thank you very much, this is super informative.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=993882022-09-28T15:47:45Zmatheusrich (Matheus Richard)matheusrichardt@gmail.com
<ul></ul><p>I don't have much to contribute here, but I'll give my personal experience with this subject.</p>
<p>I like the convenience of numbered params, but I've rarely used them (outside of throwaway scripts) because they look off.<br>
I find them even a bit confusing in some cases where you might confuse them with numbers (syntax highlighting does help, though):</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="p">).</span><span class="nf">take</span><span class="p">(</span><span class="mi">10</span><span class="p">).</span><span class="nf">map</span> <span class="p">{</span> <span class="n">_1</span> <span class="o">**</span> <span class="mi">2</span> <span class="p">}</span>
</code></pre>
<p>I feel like <code>it</code> would be much more readable in this case</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="p">).</span><span class="nf">take</span><span class="p">(</span><span class="mi">10</span><span class="p">).</span><span class="nf">map</span> <span class="p">{</span> <span class="n">it</span> <span class="o">**</span> <span class="mi">2</span> <span class="p">}</span>
</code></pre>
<p>Although sometimes I'd wish we could use <code>its</code> so it reads even more like English, but that would be a minor convenience:</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="c1"># for each user, get its name</span>
<span class="n">user_names</span> <span class="o">=</span> <span class="n">users</span><span class="p">.</span><span class="nf">map</span> <span class="p">{</span> <span class="n">its</span><span class="p">.</span><span class="nf">name</span> <span class="p">}</span>
</code></pre> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=993892022-09-28T15:58:51Zmatheusrich (Matheus Richard)matheusrichardt@gmail.com
<ul></ul><blockquote>
<p>Now I'm almost giving it up because there are more people who dislike it than I expected.</p>
</blockquote>
<p>I'm not sure how good the people here represent the whole community. My bet is most people don't even notice these feature requests unless they appear on something like RubyWeekly.</p>
<p>The fact that many here are maintainers of Ruby implementations also has a biased effect on new features, as they might represent a burden on them. I'm not saying this is a bad thing, I love the diversity of points of view that this brings! OTOH, it's fair that people that do take time to discuss things here have a bigger influence on the direction that Ruby follows.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=995102022-10-07T11:05:40Zadiel (Adiel Mittmann)
<ul></ul><p>I would like to provide a data point.</p>
<p>I have been using Ruby for 10+ years and for a long time I missed a syntax that would allow me to map things quickly. Over time I decided to always use a variable named <code>x</code> for such purposes: <code>map.keys.select{|x| x =~ /foo/}</code>. While I was happy when I heard about the <code>_1</code> syntax, I do think that the case when there's only one item to be processed is special. I find that <code>_1</code> does imply <code>_2</code> in a way and it looks out of place when there's really one item, <em>the</em> item.</p>
<p>Furthermore, I find that <code>_1</code>, <code>_2</code> must be carefully used so as to keep the code readable. And, in a way, when I'm using both <code>_1</code> and <code>_2</code>, I often feel that I've gone too far and it's better to just give names to the variables.</p>
<p>In our current code base there are:</p>
<ul>
<li>268 instances of the <code>|x|</code> syntax, which we didn't care enough to update.</li>
<li>515 instances of <code>_1</code>, of which 440 are the first token in a block.</li>
<li>2 instances of <code>_2</code>.</li>
</ul>
<p>I'm in favor of any syntax which doesn't force me to use a number when my brain is definitely not thinking of any kind of ordering, and in particular I like <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/1604">@jeremyevans0 (Jeremy Evans)</a> 's <code>@</code> syntax.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=1003792022-12-01T06:41:50Zmaedi (Maedi Prichard)
<ul></ul><p>How about <code>_@</code>? It's your friendly neighborhood local-instance variable. I'm half joking but it is a local variable that refers to instances.</p>
<p>It's nice and illegal:</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="nf">each</span> <span class="p">{</span> <span class="nb">puts</span> <span class="n">_</span><span class="err">@</span> <span class="p">}</span>
</code></pre>
<p>Looks better when it's not an outlaw:</p>
<pre><code>[1, 2, 3].each { puts _@ }
</code></pre>
<p>I've always liked just <code>@</code> but I see the point that it can be confused with instance variables, especially when it's written as <code>@.size</code> (is <code>_@.size</code> better?). But I'm hoping that the local nature of <code>_</code> can help combat that, and it fits within the existing style of <code>_1</code>, <code>_2</code> and <code>_3</code>, yet actually feels unique and like something you would want to use. Call it a "local at"?</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=1004512022-12-02T22:43:01Zmaedi (Maedi Prichard)
<ul></ul><p>Or <code>_$</code>:</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="nf">map</span> <span class="p">{</span> <span class="nb">puts</span> <span class="n">_</span><span class="err">$</span> <span class="p">}</span>
</code></pre>
<pre><code>[1, 2, 3].map { puts _$ }
</code></pre>
<p>Or even just <code>$</code> by itself:</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="nf">map</span> <span class="p">{</span> <span class="nb">puts</span> <span class="err">$</span> <span class="p">}</span>
</code></pre>
<pre><code>[1, 2, 3].map { puts $ }
</code></pre>
<p>In my opinion $ is underutilised in Ruby compared to other languages. In writing day to day code you don’t often use global variables, so $ could provide an entirely unique local “this” variable without mentally switching to the global context.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=1004532022-12-03T00:21:21Zufuk (Ufuk Kayserilioglu)
<ul></ul><p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/22201">@maedi (Maedi Prichard)</a> <code>_$</code>, and especially <code>$</code>, have the same problems as <code>@</code> in which it is super easy to confuse and hard to differentiate <code>$.size</code> vs <code>$size</code>, as mentioned here <a href="https://bugs.ruby-lang.org/issues/18980#note-28" class="external">https://bugs.ruby-lang.org/issues/18980#note-28</a></p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=1004562022-12-03T07:33:28Zfunny_falcon (Yura Sokolov)funny.falcon@gmail.com
<ul></ul><p>Ruby takes so much syntax last years. I fear it. Let's not strain our lovely language, please.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=1005072022-12-06T05:18:31Zmaedi (Maedi Prichard)
<ul></ul><p>I see that <code>$.</code> is already a <a href="https://docs.ruby-lang.org/en/2.4.0/globals_rdoc.html" class="external">pre-defined variable</a> which would make <code>$.method_name</code> difficult to parse. Then <code>_$</code> looks a little bit too close to the pre-defined variable <code>$_</code>. Though I still like <code>_@</code>.</p>
<p>Can anyone think of a solution? Anything is better than <code>_1</code>. I personally like <code>@</code> and <code>it</code> and <code>this</code> and <code>that</code> but there always seems to be some conflict with existing variables and methods. What about <code>$this</code> or <code>$it</code>? If someone somewhere ever named their global variable <code>$it</code> and used it in a block then I'm sure they would forgive us, if this unlikely situation ever happened at all.</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="nf">each</span> <span class="p">{</span> <span class="nb">puts</span> <span class="vg">$it</span> <span class="p">}</span>
</code></pre>
<p>Another thing you could do which is very Ruby is provide a special block param that acts as an object and interact with that:</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="nf">each</span> <span class="p">{</span> <span class="o">|</span><span class="err">$</span><span class="o">|</span><span class="p">.</span><span class="nf">method_name</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="nf">each</span> <span class="p">{</span> <span class="nb">puts</span> <span class="o">|</span><span class="err">$</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="nf">each</span> <span class="p">{</span> <span class="n">method_name</span><span class="p">(</span><span class="o">|</span><span class="err">$</span><span class="o">|</span><span class="p">)</span> <span class="p">}</span>
</code></pre>
<pre><code>[1, 2, 3].each { |$|.method_name }
[1, 2, 3].each { puts |$| }
[1, 2, 3].each { method_name(|$|) }
</code></pre> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=1018742023-02-14T19:32:18ZrubyFeedback (robert heiler)
<ul></ul><p>If I recall correctly I suggested @1 @2 and so forth.</p>
<p>At a later time _1 _2 and so forth was added, which is not entirely the same. I<br>
then realised that the suggestion was actually much older than my suggestion,<br>
and the ruby core team often said they may build upon suggestions and modify<br>
it.</p>
<p>What surprised me was that one of my use case was not implemented, at the least<br>
back then.</p>
<p>Which was:</p>
<pre><code>@large_collection_as_an_array.each {|cats_with_a_fluffy_tail, dogs_with_cute_ears, ships_with_red_painting, cars_without_a_door|
}
</code></pre>
<p>For such a situation, in particular in IRB as well as in quick debugging, I wanted to<br>
be able to refer to the element at hand quickly, without having to remember the name<br>
as such.</p>
<p>So I could then do:</p>
<pre><code>pp @1
pp @3
</code></pre>
<p>And so on.</p>
<p>Unfortunately it seems as if that was not considered, and it was (back then at<br>
the least) made forbidden to assign proper (long) names to the block variables.<br>
The syntax was also changed; I find _1 _2 a bit hard to read.</p>
<p>I should note that I remember the other proposal about "it". I don't have a strong<br>
opinion against it. But I also don't feel particularly committed towards wanting<br>
to use it. The whole point of @1 @2 was actually to help in prototyping, e. g. to<br>
be faster when you write code initially. It's not a huge saving of time, admittedly<br>
so, but it does help, and I think in particular for IRB it can really be helpful<br>
(I'd wish we could still use _1 _2 and so forth together with real names of the<br>
variables; my use case was that I am fine with the initial block names, and I<br>
would keep them, but in the middle of writing more code, I just want to refer<br>
to the variable without necessarily always needing to remember the name. I have<br>
to scroll back with my crappy editor.)</p>
<p>maedi wrote:</p>
<blockquote>
<p>I see that $. is already a pre-defined variable which would<br>
make $.method_name difficult to parse.</p>
</blockquote>
<p>All $-variables are quite hard to remember. With @1 or _1 this is<br>
a bit different because, like in a regex, you just refer to some<br>
specific group by number rather than a name. (Or just syntax, as is<br>
the case with the various $: $< and what not.)</p>
<p>maedi wrote:</p>
<blockquote>
<p>Though I still like _@.</p>
</blockquote>
<p>That one trips my brain up. I think we should be conservative about<br>
syntax. Perlisms can be useful due to begin succinct, but readability<br>
is also a useful metric to have.</p>
<p>What surprised me the most is that people began to include _1 _2 and<br>
so forth in real production code. To me it is purely a method of<br>
testing and debugging aid; but I guess the moment you add functionality<br>
someone is going to use it, and a few of these change their style<br>
to include these.</p>
<p>maedi wrote:</p>
<blockquote>
<p>Another thing you could do which is very Ruby is provide a<br>
special block param that acts as an object and interact<br>
with that:</p>
</blockquote>
<p>I have no real problem with "it", even though I most likely won't<br>
use it. But we could use "it" also as reference object via<br>
[] method e. g. it[0], it[1] in addition to "normal" use of "it".</p>
<p>adiel wrote:</p>
<blockquote>
<p>Over time I decided to always use a variable named x for such<br>
purposes: map.keys.select{|x| x =~ /foo/}.</p>
</blockquote>
<p>I kind of use longer names such as:</p>
<pre><code>map.keys.select {|entry| entry =~ /foo/}
</code></pre>
<p>But using short names is also understandable. I tend to use _<br>
most of the time, but sometimes I also use short variable<br>
names such as "x".</p>
<p>Matheus wrote:</p>
<blockquote>
<p>Although sometimes I'd wish we could use its so it reads<br>
even more like English, but that would be a minor convenience:</p>
</blockquote>
<pre><code># for each user, get its name
user_names = users.map { its.name }
</code></pre>
<p>That is similar to the File.exist? versus File.exists? situation.</p>
<p>In plain english the "its name" may be more correct. In an OOP<br>
centric point of view, you are asking a specific object via a<br>
method call (sending a message). Although if "it" were to be<br>
added, we could also add an alias to it called "its". ;)</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=1050122023-10-19T04:15:36Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/105012/diff?detail_id=65778">diff</a>)</li></ul> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=1055632023-12-07T07:08:39Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/105563/diff?detail_id=65964">diff</a>)</li><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>k0kubun (Takashi Kokubun)</i></li><li><strong>Target version</strong> set to <i>3.4</i></li></ul><p>In today's Developers Meeting, <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/13">@matz (Yukihiro Matsumoto)</a> accepted to warn <code>it</code> in Ruby 3.3 and add <code>it</code> in Ruby 3.4. Quote from the meeting notes:</p>
<blockquote>
<ul>
<li>matz: accept <code>it</code> on Ruby 3.4.
<ul>
<li>ruby 3.3 will warn and ruby 3.4 will use the new semantics</li>
<li>The warning should be printed always (even without $VERBOSE)</li>
</ul>
</li>
</ul>
</blockquote>
<p>I also copied the discussed specification to the ticket description. In Ruby 3.3, <code>it</code> should be warned only when <code>it</code> will behave like <code>_1</code> in Ruby 3.4.</p> Ruby master - Feature #18980: Re-reconsider numbered parameters: `it` as a default block parameterhttps://bugs.ruby-lang.org/issues/18980?journal_id=1058432023-12-25T09:15:52Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li></ul><p>Applied in changeset <a class="changeset" title="Implement `it` (#9199) [[Feature #18980]](https://bugs.ruby-lang.org/issues/18980) Co-authored-..." href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/44592c4e20a17946b27c50081aee96802db981e6">git|44592c4e20a17946b27c50081aee96802db981e6</a>.</p>
<hr>
<p>Implement <code>it</code> (<a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: win32.h is not installed by '(n)make install) (Closed)" href="https://bugs.ruby-lang.org/issues/9199">#9199</a>)</p>
<p><a href="https://bugs.ruby-lang.org/issues/18980" class="external">[Feature #18980]</a></p>
<p>Co-authored-by: Yusuke Endoh <a href="mailto:mame@ruby-lang.org" class="email">mame@ruby-lang.org</a></p>