https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112016-06-23T01:47:43ZRuby Issue Tracking SystemRuby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=593132016-06-23T01:47:43Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul></ul><p>Loren Segal wrote:</p>
<blockquote>
<p>should be back compat unless someone already has a "<code>Boolean</code>" class at toplevel out there.</p>
</blockquote>
<p>You failed here.</p>
<p><a href="https://github.com/search?l=ruby&q=%22class+Boolean%22&type=Code" class="external">https://github.com/search?l=ruby&q=%22class+Boolean%22&type=Code</a><br>
<a href="https://rubygems.org/search?query=Boolean" class="external">https://rubygems.org/search?query=Boolean</a></p>
<p>I guess it's too late.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=593142016-06-23T02:10:12Zolivierlacan (Olivier Lacan)hi@olivierlacan.com
<ul></ul><p>Shyouhei Urabe wrote:</p>
<blockquote>
<p>You failed here.</p>
</blockquote>
<p>This admittedly could be lost in translation but I don't think this a very nice way to react to Loren's proposal. He didn't fail here. He just proposed something. You either think it's a good idea or a bad idea. I wish you could provide your opinion a bit more kindly.</p>
<blockquote>
<p><a href="https://github.com/search?l=ruby&q=%22class+Boolean%22&type=Code" class="external">https://github.com/search?l=ruby&q=%22class+Boolean%22&type=Code</a><br>
<a href="https://rubygems.org/search?query=Boolean" class="external">https://rubygems.org/search?query=Boolean</a></p>
<p>I guess it's too late.</p>
</blockquote>
<p>I can change the search query to <code>Integer</code> and provide similarly dubious reasons why <code>Integer</code> would be bad idea:</p>
<p><a href="https://github.com/search?l=ruby&q=%22class+Integer%22&type=Code" class="external">https://github.com/search?l=ruby&q=%22class+Integer%22&type=Code</a><br>
<a href="https://rubygems.org/search?query=Integer" class="external">https://rubygems.org/search?query=Integer</a></p>
<p>I don't think this is very solid counterpoint.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=593152016-06-23T02:24:40Zlsegal (Loren Segal)lsegal@soen.ca
<ul></ul><p>Shyouhei Urabe wrote:</p>
<blockquote>
<p><a href="https://github.com/search?l=ruby&q=%22class+Boolean%22&type=Code" class="external">https://github.com/search?l=ruby&q=%22class+Boolean%22&type=Code</a><br>
<a href="https://rubygems.org/search?query=Boolean" class="external">https://rubygems.org/search?query=Boolean</a></p>
<p>I guess it's too late.</p>
</blockquote>
<p>As Olivier pointed out, isn't this an argument to revert the <code>Integer</code> patch? Why is the <code>Integer</code> change okay but not <code>Boolean</code>?</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=593162016-06-23T02:51:02Zlsegal (Loren Segal)lsegal@soen.ca
<ul></ul><p>edit: as a sidenote, adding a <code>Boolean</code> class to Ruby-core is unlikely to break any of the linked code, because Ruby is just defining an empty <code>Boolean</code> class. Existing libraries will just re-open the class as normal.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=593182016-06-23T04:24:49Zdjberg96 (Daniel Berger)
<ul></ul><p>This was brought up in the past a lot:</p>
<p><a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/96321" class="external">http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/96321</a></p>
<p><a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/186881" class="external">http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/186881</a></p>
<p>There's also this: <a href="http://stackoverflow.com/questions/3192978/why-does-ruby-have-trueclass-and-falseclass-instead-of-a-single-boolean-class" class="external">http://stackoverflow.com/questions/3192978/why-does-ruby-have-trueclass-and-falseclass-instead-of-a-single-boolean-class</a></p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=593192016-06-23T04:46:40Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul></ul><ul>
<li>I'm not a big fan of <code>Integer</code>, too. However,</li>
<li>
<code>Integer</code> has been there since the beginning. It was just not used before. You are always free to reopen this class. <code>Boolean</code> on the other hand, is something new. The situation is different.</li>
<li>Because most wild <code>Boolean</code> implementation I have seen inherits <code>Object</code> (or depending on project <code>ActiveRecord::Base</code>), I'm sorry I guess Loren's suggested implementation that inherits <code>BasicObject</code> won't interface.</li>
</ul> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=593202016-06-23T05:25:12Zshugo (Shugo Maeda)
<ul></ul><p>At <a href="http://qiita.com/yatemmma/items/3597a0e20556fb846d3f" class="external">http://qiita.com/yatemmma/items/3597a0e20556fb846d3f</a>, Matz explained the reason why Ruby doesn't have Boolean.</p>
<ul>
<li>
<code>true</code> and <code>false</code> are just representative samples of boolean values.</li>
<li>There is no method to be defined in <code>Boolean</code> (e.g., implementations of <code>TrueClass#&</code> and <code>FalseClass#&</code> are different).</li>
<li>The use case of <code>Boolean</code> is therefore limited to <code>kind_of?</code> checks, and it prevents duck typing.</li>
</ul>
<p>However <code>Boolean</code> might be useful to extend <code>true</code> and <code>false</code> in user code (e.g., refining <code>Boolean</code>).<br>
Another use case is type checking system, but it might not be a good idea to consider a class a type.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=593212016-06-23T07:21:07Zlsegal (Loren Segal)lsegal@soen.ca
<ul></ul><p>In reality it's very common to treat <code>true</code>/<code>false</code> as a separate thing. The "everything is boolean" argument falls apart when you have something like var args in a method declaration and you want to perform distinct operations based on the actual value.</p>
<p>This actually comes up fairly often:</p>
<p><a href="https://github.com/search?p=2&q=is_a%3F+TrueClass&ref=searchresults&type=Code&utf8=%E2%9C%93" class="external">https://github.com/search?p=2&q=is_a%3F+TrueClass&ref=searchresults&type=Code&utf8=%E2%9C%93</a></p>
<p>And that's only the checks for <code>is_a?</code> syntax, because GitHub cannot search for "<code>TrueClass === x</code>" style code. But if it's an anti-pattern, it's an extremely common one.</p>
<p>I didn't realize about Integer being around though, that certainly changes things.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=593372016-06-24T07:23:51Zduerst (Martin Dürst)duerst@it.aoyama.ac.jp
<ul></ul><p>Loren Segal wrote:</p>
<blockquote>
<p>This actually comes up fairly often:</p>
<p><a href="https://github.com/search?p=2&q=is_a%3F+TrueClass&ref=searchresults&type=Code&utf8=%E2%9C%93" class="external">https://github.com/search?p=2&q=is_a%3F+TrueClass&ref=searchresults&type=Code&utf8=%E2%9C%93</a></p>
<p>And that's only the checks for <code>is_a?</code> syntax, because GitHub cannot search for "<code>TrueClass === x</code>" style code. But if it's an anti-pattern, it's an extremely common one.</p>
</blockquote>
<p>The search results aren't very convincing to me. Where there's a <code>Boolean</code> <code>class</code> or <code>module</code>, it's usually really tiny. And there are checks for <code>TrueClass</code> and <code>FalseClass</code> that I'd write as checks for <code>true</code> and <code>false</code>, which would make the code a lot shorter.</p>
<p>Actually, because both <code>true</code> and <code>false</code> are singletons, <code>TrueClass</code> and <code>FalseClass</code> look like overkill; in Ruby's ducktyping world, most if not all things would work just as well with the necessary methods for <code>true</code> and <code>false</code> being defined directly as singleton methods on <code>true</code> and <code>false</code>.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=593472016-06-24T15:12:45Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Let's leave <code>TrueClass</code>/<code>FalseClass</code>!!</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=594652016-07-02T10:14:45Zsawa (Tsuyoshi Sawada)
<ul></ul><p>Martin Dürst wrote:</p>
<blockquote>
<p>Actually, because both <code>true</code> and <code>false</code> are singletons, <code>TrueClass</code> and <code>FalseClass</code> look like overkill; in Ruby's ducktyping world, most if not all things would work just as well with the necessary methods for <code>true</code> and <code>false</code> being defined directly as singleton methods on <code>true</code> and <code>false</code>.</p>
</blockquote>
<p>My understanding is that defining a singleton method on an object creates a singleton class for that object (and the method is actually an instance method of the singleton class). And in case of <code>true</code>, <code>false</code> or <code>nil</code>, the singleton classes are in fact the classes in question:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="kp">true</span><span class="p">.</span><span class="nf">singleton_class</span> <span class="c1"># => TrueClass</span>
<span class="kp">false</span><span class="p">.</span><span class="nf">singleton_class</span> <span class="c1"># => FalseClass</span>
<span class="kp">nil</span><span class="p">.</span><span class="nf">singleton_class</span> <span class="c1"># => NilClass</span>
</code></pre>
<p>so there is no way to get rid of these classes. We don't need to worry as</p>
<p>Nobuyoshi Nakada wrote:</p>
<blockquote>
<p>Let's leave <code>TrueClass</code>/<code>FalseClass</code>!!</p>
</blockquote>
<p>And by the way for the <code>Boolean</code> class proposed in this thread, it surely is un-useful.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=596742016-07-19T08:29:31Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Rejected</i></li></ul><p>Rejected for several reasons:</p>
<ul>
<li>many gems and libraries had already introduced <code>Boolean</code> class. I don't want to break them.</li>
<li>
<code>true</code> and <code>false</code> are the only representative of true-false values. In Ruby. <code>nil</code> and <code>false</code> are falsy values, and everything else is a true value. There's no meaning for having a superclass of <code>TrueClass</code> and <code>FalseClass</code> as <code>Boolean</code>.</li>
</ul>
<p>Matz.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=608142016-10-11T02:30:37Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul><li><strong>Has duplicate</strong> <i><a class="issue tracker-1 status-6 priority-4 priority-default closed" href="/issues/12827">Bug #12827</a>: Add Boolean data type.</i> added</li></ul> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611222016-10-30T23:00:37Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul></ul><p>The fact that so many gems are introducing "<code>class Boolean</code>" is an argument FOR it not AGAINST it, IMHO. Because when this code is loaded together, it might behave strangely if there is no shared meaning for "<code>class Boolean</code>".</p>
<p>Having a <code>Boolean(String)</code> constructor would be useful.</p>
<p>Having a class named <code>Boolean</code> would make things more readable, for example here: <a href="http://sequel.jeremyevans.net/rdoc/files/doc/schema_modification_rdoc.html#label-Column+types" class="external">http://sequel.jeremyevans.net/rdoc/files/doc/schema_modification_rdoc.html#label-Column+types</a> - you can see that because there is no <code>Boolean</code> class, they resort to, IMHO quite a strange naming convention, using either <code>TrueClass</code> or <code>FalseClass</code>.</p>
<p>The naming of <code>TrueClass</code> and <code>FalseClass</code> are also inconsistent with other names, e.g. it's not <code>IntegerClass</code> or <code>FloatClass</code> or <code>StringClass</code>. It's a little bit ugly. (EDIT: or <code>ZeroClass</code>, <code>OneClass</code>, etc :)</p>
<blockquote>
<p>There's no meaning for having a superclass of TrueClass and FalseClass as Boolean</p>
</blockquote>
<p>I believe you are wrong on this point. There is meaning.</p>
<p>The meaning is that "This variable is of class <code>Boolean</code>".</p>
<p>There is one example I can think of:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1">#!/usr/bin/env ruby</span>
<span class="n">x</span> <span class="o">=</span> <span class="kp">true</span>
<span class="c1"># x = false</span>
<span class="k">case</span> <span class="n">x</span>
<span class="k">when</span> <span class="no">TrueClass</span>
<span class="nb">puts</span> <span class="s2">"trueclass"</span>
<span class="k">when</span> <span class="no">FalseClass</span>
<span class="nb">puts</span> <span class="s2">"falseclass"</span>
<span class="c1"># How can we implement this?</span>
<span class="c1"># when Boolean</span>
<span class="k">end</span>
</code></pre>
<p>Situations were this kind of logic comes up include serialisation and deserialisation libraries, data modelling, etc.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611232016-10-30T23:35:01Zphluid61 (Matthew Kerwin)matthew@kerwin.net.au
<ul></ul><p>Samuel Williams wrote:</p>
<blockquote>
<p>The fact that so many gems are introducing "<code>class Boolean</code>" is an argument FOR it not AGAINST it, IMHO. Because when this code is loaded together, it might behave strangely if there is no shared meaning for "<code>class Boolean</code>".</p>
</blockquote>
<p>But that's how things already are, and the market deals with it just fine. Adding a core '<code>Boolean</code>' class means every existing implementation, even those only ever used in isolation, will suddenly have a conflict.</p>
<blockquote>
<blockquote>
<p>There's no meaning for having a superclass of TrueClass and FalseClass as Boolean</p>
</blockquote>
<p>I believe you are wrong on this point. There is meaning.</p>
<p>The meaning is that "This variable is of class Boolean".</p>
<p>There is one example I can think of:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1">#!/usr/bin/env ruby</span>
<span class="n">x</span> <span class="o">=</span> <span class="kp">true</span>
<span class="c1"># x = false</span>
<span class="k">case</span> <span class="n">x</span>
<span class="k">when</span> <span class="no">TrueClass</span>
<span class="nb">puts</span> <span class="s2">"trueclass"</span>
<span class="k">when</span> <span class="no">FalseClass</span>
<span class="nb">puts</span> <span class="s2">"falseclass"</span>
<span class="c1"># How can we implement this?</span>
<span class="c1"># when Boolean</span>
<span class="k">end</span>
</code></pre>
<p>Situations were this kind of logic comes up include serialisation and deserialisation libraries, data modelling, etc.</p>
</blockquote>
<p>If that was:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">case</span> <span class="n">x</span>
<span class="k">when</span> <span class="no">Boolean</span>
<span class="c1">#do something</span>
<span class="k">end</span>
</code></pre>
<p>What "something" would you do that is identical for both <code>True</code> and <code>False</code>? Or put another way, what method would you define inside <code>class Boolean</code> that is useful to both <code>True</code> and <code>False</code>? This comes back to one of Ruby's basic OO-tenets: that classes have shared <em>functionality</em>, not a shared <em>type</em>.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611272016-10-31T01:14:38Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul></ul><blockquote>
<p>But that's how things already are, and the market deals with it just fine.</p>
</blockquote>
<p>Well, I know you are being metaphorical ("market deals with it"). But this is not really a case of a market, and I prefer DRY for many reasons. There should be one correct implementation and it makes sense for it to be within Ruby.</p>
<p>To be explicit about it: If I include two gems, and they both define "<code>class Boolean</code>", and they collide for some reason, it's a problem for me, and it might not even be an obvious problem.</p>
<blockquote>
<p>What "something" would you do that is identical for both True and False?</p>
</blockquote>
<p>Sometimes you need to handle multiple data types this way because the functionality is on core classes that you don't want to extend. It's similar to how type classes work in Haskell.</p>
<p>So, as a basic example, sometimes you want to be declarative about, say, an API:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">format_response</span><span class="p">(</span><span class="ss">name: </span><span class="no">String</span><span class="p">,</span> <span class="ss">age: </span><span class="no">Integer</span><span class="p">,</span> <span class="ss">happy: </span><span class="no">Boolean</span><span class="p">)</span>
</code></pre>
<p>Another example of this would be libraries like optparse, slop, sequel, etc, where they'd like to declaratively specify that something is a Boolean, e.g.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">option</span> <span class="s1">'--foo'</span><span class="p">,</span> <span class="ss">type: </span><span class="no">Boolean</span>
<span class="c1"># or</span>
<span class="n">create_table</span> <span class="ss">:foo</span> <span class="k">do</span> <span class="o">|</span><span class="n">t</span><span class="o">|</span>
<span class="n">t</span><span class="p">.</span><span class="nf">happy</span> <span class="ss">type: </span><span class="no">Boolean</span>
<span class="k">end</span>
</code></pre>
<p>Another use case would be where you want to do validation, conversion or deal with a type as specified by the user, e.g.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">case</span> <span class="vi">@type</span>
<span class="k">when</span> <span class="no">Integer</span>
<span class="no">Integer</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
<span class="k">when</span> <span class="no">Float</span>
<span class="no">Float</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
<span class="k">when</span> <span class="no">Boolean</span>
<span class="no">Boolean</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
<p>Unfortunately in Ruby, the type constructors (<code>Kernel.Integer</code>) are free functions, not part of the class, e.g you can't write <code>Integer.parse(input)</code>. You need to write (verbosely on purpose) <code>Kernel.Integer(input)</code>. It's not very OO.</p>
<p>Another case would be handling the above, e.g. <code>Boolean.parse(input)</code> or <code>Kernel.Boolean(input)</code>. It would make sense if they could turn the string representations into boolean values and throw an <code>ArgumentError</code> if not convertable.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611292016-10-31T03:35:23Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul></ul><p>It's also interesting to note, so many people are working around this:</p>
<p>Searching on github for:</p>
<p>"is_a? TrueClass FalseClass" gives 90,000 results.</p>
<p><a href="https://github.com/search?p=2&q=is_a%3F+TrueClass&ref=searchresults&type=Code&utf8=%E2%9C%93" class="external">https://github.com/search?p=2&q=is_a%3F+TrueClass&ref=searchresults&type=Code&utf8=✓</a></p>
<p>"module Boolean TrueClass FalseClass" gives 63,000 results.</p>
<p><a href="https://github.com/search?utf8=%E2%9C%93&q=module+Boolean+TrueClass+FalseClass&type=Code&ref=searchresults" class="external">https://github.com/search?utf8=✓&q=module+Boolean+TrueClass+FalseClass&type=Code&ref=searchresults</a></p>
<p>Even I'm surprised by the number of people working around this issue!</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611342016-10-31T03:51:30Zrrroybbbean (RRRoy BBBean)
<ul></ul><p>The terms "truthy" and "falsey" were used by Douglas Crockford in his<br>
series of JavaScript lectures at Yahoo about 5 years ago. A value is<br>
"truthy" if treated as true by a conditional. A value is "falsey" if<br>
treated as false by a conditional.</p>
<p>Ruby has possibly the simplest, cleanest and easiest to use distinction<br>
between "truthy" and "falsey" values of any programming language: <code>nil</code><br>
and <code>false</code> are falsey, everything else is truthy.</p>
<p>Compare Ruby's to PHP's or JavaScript's allocation of truthy and falsey,<br>
where empty strings and empty arrays and even zero can be falsey. If <code>0</code><br>
is falsey, should <code>0.0</code> be false? What about rounding errors? How about<br>
complex numbers? expressed in rectangular notation? expressed in polar<br>
notation? How about multidimensional arrays that contain no values other<br>
than arrays? How about empty dictionaries? Should they truthy or falsey?<br>
The richer the language and it's data structures, the more vexing these<br>
issues become.</p>
<p>Ruby has reduced the confusion to a minimum by keeping the falsey values<br>
to a minimum: <code>false</code> and <code>nil</code>. Everything else is truthy. And Ruby<br>
accomplishes this without a <code>Boolean</code> class. Adding a <code>Boolean</code> class to<br>
Ruby is not necessary, and it would be profoundly inelegant.</p>
<p>I quote the definition of elegance provided by Alex W. White in his 'The<br>
Elements of Graphic Design': "Distill the essential from the mass of<br>
confusing muchness. Nothing may be missing and nothing may be<br>
extraneous. This is the definition of elegance."</p>
<p>There is also a well-know translation of a quotation by the famous<br>
French pioneer in aviation Antoine de Saint-Exupéry (as translated by<br>
Lewis Galantière): "... perfection is finally attained not when there is<br>
no longer anything to add, but when there is no longer anything to take<br>
away ..."</p>
<p>Please don't add a <code>Boolean</code> class to Ruby; it doesn't need a <code>Boolean</code> class.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611362016-10-31T04:32:47Zphluid61 (Matthew Kerwin)matthew@kerwin.net.au
<ul></ul><p>Samuel Williams wrote:</p>
<blockquote>
<blockquote>
<p>But that's how things already are, and the market deals with it just fine.</p>
</blockquote>
<p>Well, I know you are being metaphorical ("market deals with it"). But this is not really a case of a market, and I prefer DRY for many reasons. There should be one correct implementation and it makes sense for it to be within Ruby.</p>
</blockquote>
<p>It's not a metaphor, it's the real world. Ruby gems exist in open competition, and developers have the opportunity to choose between (or create alternatives to) any available gems in the ecosystem.</p>
<p>If there should be one "correct" implementation, why do we have gems at all? <em>Everything</em> should be in the core. And that's without even starting the big argument about which approach should be considered "correct." (Anyone who says <code>"N"</code> is falsy-y in all cases is going to have some serious arguing ahead of them.)</p>
<blockquote>
<p>To be explicit about it: If I include two gems, and they both define "<code>class Boolean</code>", and they collide for some reason, it's a problem for me, and it might not even be an obvious problem.</p>
</blockquote>
<p>Indeed. That goes back to an open marketplace and market forces. You say, "If I do this..." but I say, "People already live with that possibility and seem to be surviving just fine."</p>
<blockquote>
<blockquote>
<p>What "something" would you do that is identical for both True and False?</p>
</blockquote>
<p>Sometimes you need to handle multiple data types this way because the functionality is on core classes that you don't want to extend. It's similar to how type classes work in Haskell.</p>
<p><em>[snip]</em></p>
</blockquote>
<p>Everything you've listed there is a <em>type</em>. Ruby doesn't do types like that. You're conflating the class hierarchy with types.</p>
<blockquote>
<p>Unfortunately in Ruby, the type constructors (<code>Kernel.Integer</code>) are free functions, not part of the class, e.g you can't write <code>Integer.parse(input)</code>. You need to write (verbosely on purpose) <code>Kernel.Integer(input)</code>. It's not very OO.</p>
</blockquote>
<p>They're not constructors; <code>Integer</code>s (well, <code>Fixnum</code>s) are singleton and cannot be instantiated. The methods you're talking about are for coercion. (And very specific coercion at that.)</p>
<p>If you want to talk about OO, the casting methods (e.g. <code>#to_i</code>) are defined on the object-to-be-recast, or an intermediate expert. The destination class doesn't <em>and shouldn't</em> have responsibility to understand every possible class or type of object, and know how to convert them all to an instance of itself. There are all sorts of anti-patterns in there. (Said another way: a <code>String</code> should know whether it represents a 'true' or 'false' value, or there should be an object that knows just enough about <code>String</code>s and booleans to be able to manage the conversion.)</p>
<blockquote>
<p>Another case would be handling the above, e.g. <code>Boolean.parse(input)</code> or <code>Kernel.Boolean(input)</code>. It would make sense if they could turn the string representations into boolean values and throw an <code>ArgumentError</code> if not convertable.</p>
</blockquote>
<p>I posit that it should be something like <code>String#to_bool</code>, since the String is the thing that knows whether and how it represents a boolean value.</p>
<p>There is no value in defining a <code>Boolean</code> superclass of both <code>True</code> and <code>False</code>.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611462016-10-31T06:24:14Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Samuel Williams wrote:</p>
<blockquote>
<p>Having a class named <code>Boolean</code> would make things more readable, for example here: <a href="http://sequel.jeremyevans.net/rdoc/files/doc/schema_modification_rdoc.html#label-Column+types" class="external">http://sequel.jeremyevans.net/rdoc/files/doc/schema_modification_rdoc.html#label-Column+types</a> - you can see that because there is no <code>Boolean</code> class, they resort to, IMHO quite a strange naming convention, using either <code>TrueClass</code> or <code>FalseClass</code>.</p>
</blockquote>
<p>It's a choice by that library author.<br>
They are not classes but methods, there can be <code>Boolean</code> method in the library.<br>
Not providing such method is the choice by the author.</p>
<blockquote>
<p>The naming of <code>TrueClass</code> and <code>FalseClass</code> are also inconsistent with other names, e.g. it's not <code>IntegerClass</code> or <code>FloatClass</code> or <code>StringClass</code>. It's a little bit ugly. (EDIT: or <code>ZeroClass</code>, <code>OneClass</code>, etc :)</p>
</blockquote>
<p>Indeed.<br>
We don't need the names for singleton classes of <code>true</code>, <code>false</code>, and <code>nil</code>, and should remove them all.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611502016-10-31T14:50:28Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>I'd just like to add a real situation where I missed a <code>Boolean</code> class recently.</p>
<p>A web request takes an array of values in a JSON encoded string and before processing the data the server-side handler will try to validate the input by comparing the elements type. If <code>Boolean</code> existed, the validation rule would be something like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">input</span> <span class="o">=</span> <span class="no">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="s1">'value'</span><span class="p">])</span>
<span class="k">raise</span> <span class="no">InvalidInput</span><span class="p">,</span> <span class="s1">'size must be 6'</span> <span class="k">unless</span> <span class="n">input</span><span class="p">.</span><span class="nf">size</span> <span class="o">==</span> <span class="mi">6</span>
<span class="k">raise</span> <span class="no">InvalidInput</span><span class="p">,</span> <span class="s2">"types don't match"</span> <span class="k">unless</span> <span class="n">input</span><span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:class</span><span class="p">)</span> <span class="o">==</span>
<span class="p">[</span><span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">Boolean</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">Boolean</span><span class="p">]</span>
</code></pre>
<p>As you can imagine, the validation took more effort without the existence of <code>Boolean</code>. Something like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">input</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span> <span class="o">==</span> <span class="kp">false</span> <span class="o">||</span> <span class="n">x</span> <span class="o">==</span> <span class="kp">true</span> <span class="p">?</span> <span class="ss">:boolean</span> <span class="p">:</span> <span class="n">x</span><span class="p">.</span><span class="nf">class</span> <span class="p">}</span> <span class="o">==</span>
<span class="p">[</span><span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="ss">:boolean</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="ss">:boolean</span><span class="p">]</span>
</code></pre> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611512016-10-31T14:51:43Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Actually, this isn't a good example as it would return <code>TrueClass</code> or <code>FalseClass</code> rather than <code>Boolean</code>...</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611522016-10-31T14:53:37Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Maybe something like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">input</span><span class="p">.</span><span class="nf">zip</span><span class="p">([</span><span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">Boolean</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">Boolean</span><span class="p">]).</span><span class="nf">all?</span><span class="p">{</span><span class="o">|</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span><span class="o">|</span> <span class="n">c</span> <span class="o">===</span> <span class="n">i</span> <span class="p">}</span>
</code></pre> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611552016-10-31T23:08:23Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul></ul><blockquote>
<p>It's a choice by that library author. They are not classes but methods, there can be <code>Boolean</code> method in the library.</p>
</blockquote>
<p>Nobu, you are not looking deep enough.</p>
<p><a href="https://github.com/jeremyevans/sequel/blob/c39594dd35b3f8a8975b05be156ba664f1630804/lib/sequel/database/schema_generator.rb#L57-L61" class="external">https://github.com/jeremyevans/sequel/blob/c39594dd35b3f8a8975b05be156ba664f1630804/lib/sequel/database/schema_generator.rb#L57-L61</a></p>
<p>The author makes methods to produce the types. The type name must be the same. My feeling is that if a <code>Boolean</code> type existed, they would prefer it.</p>
<blockquote>
<p>"Distill the essential from the mass of<br>
confusing muchness. Nothing may be missing and nothing may be<br>
extraneous. This is the definition of elegance."</p>
</blockquote>
<p>Yes, and if you apply this logic, why have two classes when one would be better in every way?</p>
<blockquote>
<p>There is no value in defining a <code>Boolean</code> superclass of both <strong><code>TrueClass</code> and <code>FalseClass</code></strong>.</p>
</blockquote>
<p>There is value in the check <code>x.is_a? Boolean</code>. The value is in the check itself, finding out if x contains [true, false]. And the value is in the consistency that there is a single class name "<code>Boolean</code> which is polymorphic over the set of classes <code>Integer</code>, <code>Float</code>, <code>Numeric</code>, <code>String</code>, etc, which are used over and over again in code which does formatting, type checking, serialisation, deserialisation, database modelling, etc.</p>
<p>The evidence is overwhelming. There are 150,000 instances of code working around the lack of <code>Boolean</code> on GitHub. At what point do you draw the line and say "Yeah, enough people are doing this, it might make sense to bring this into the core language".</p>
<p>No other language structures booleans around a "<code>TrueClass</code>" and "<code>FalseClass</code>":</p>
<ul>
<li>Python has <code>bool</code> data type.</li>
<li>C has <code>#include <stdbool.h></code>
</li>
<li>C++ has <code>bool</code>
</li>
<li>Java has <code>bool</code> and <code>class Boolean</code>
</li>
<li>JavaScript has <code>Boolean</code>
</li>
<li>Smalltalk has <code>Boolean</code>
</li>
<li>CLISP has <code>BOOLEAN</code>
</li>
</ul>
<blockquote>
<p>but I say, "People already live with that possibility and seem to be surviving just fine."</p>
</blockquote>
<p>Is Ruby a language just to survive or is it a language to provide the tools programmers need to be happy?</p>
<p>I say, that every person who wrote their own Boolean class, wasted an hour of their time trying to figure it out. On GitHub, there are 2,080,658 results for "class Boolean". I know it's an overestimate, but that gives us an upper bound of 228+ years of programmer time. Matz, how can you live with yourself :D (purely for comic effect, honestly we all love you).</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611562016-10-31T23:48:40Zphluid61 (Matthew Kerwin)matthew@kerwin.net.au
<ul></ul><p>Samuel Williams wrote:</p>
<blockquote>
<blockquote>
<p>There is no value in defining a <code>Boolean</code> superclass of both <strong><code>TrueClass</code> and <code>FalseClass</code></strong>.</p>
</blockquote>
<p>There is value in the check <code>x.is_a? Boolean</code>. The value is in the check itself, finding out if x contains [true, false]. And the value is in the consistency that there is a single class name "<code>Boolean</code> which is polymorphic over the set of classes <code>Integer</code>, <code>Float</code>, <code>Numeric</code>, <code>String</code>, etc, which are used over and over again in code which does formatting, type checking, serialisation, deserialisation, database modelling, etc.</p>
</blockquote>
<p>You keep saying things like "polymorphic," but you still haven't answered the question which is fundamental to this whole debate: what method would you define on <code>class Boolean</code> that applies identically to both <code>TRUE</code> and <code>FALSE</code>?</p>
<p>An object's <code>.class</code> is <strong>not the same</strong> as its type.</p>
<p>If they never quack the same, they aren't ducks. A class that doesn't define a #quack method is not a useful class, in the Ruby sense.</p>
<blockquote>
<p>No other language structures booleans around a "TrueClass" and "FalseClass":</p>
<ul>
<li>Python has <code>bool</code> data type.</li>
<li>C has <code>#include <stdbool.h></code>
</li>
<li>C++ has <code>bool</code>
</li>
<li>Java has <code>bool</code> and <code>class Boolean</code>
</li>
<li>JavaScript has <code>Boolean</code>
</li>
<li>Smalltalk has <code>Boolean</code>
</li>
<li>CLISP has <code>BOOLEAN</code>
</li>
</ul>
</blockquote>
<p>As has been mentioned already, <code>TrueClass</code> and <code>FalseClass</code> (and <code>NilClass</code>) are just named eigenclasses of the objects <code>TRUE</code> and <code>FALSE</code> (and <code>NIL</code>). There's no "structure" around them beyond the fact that <em>every</em> object (including the three listed above) has one; these three just happen to have a little quirk in their inheritance.</p>
<p>Perhaps it would be better if <code>TRUE.class</code> (etc.) returned <code>Object</code>; being an instance of the eigenclass is rather confusing.</p>
<blockquote>
<blockquote>
<p>but I say, "People already live with that possibility and seem to be surviving just fine."</p>
</blockquote>
<p>Is Ruby a language just to survive or is it a language to provide the tools programmers need to be happy?</p>
</blockquote>
<p>(Semantics: "surviving just fine" implies satisfaction and comfort (i.e. happiness.) That notwithstanding:)</p>
<p>The latter, if the "programmers" in question are Matz. Ruby isn't designed to make Java or C++ or 8086 programmers happy, it's designed for Ruby programmers. In Ruby class is not type, and type is defined by behaviour. You have to learn this if you want to be a happy Ruby programmer.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611572016-11-01T00:01:24Zphluid61 (Matthew Kerwin)matthew@kerwin.net.au
<ul></ul><p>Rodrigo Rosenfeld Rosas wrote:</p>
<blockquote>
<p>I'd just like to add a real situation where I missed a <code>Boolean</code> class recently.</p>
<p>A web request takes an array of values in a JSON encoded string and before processing the data the server-side handler will try to validate the input by comparing the elements type. If <code>Boolean</code> existed, the validation rule would be something like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">input</span> <span class="o">=</span> <span class="no">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="s1">'value'</span><span class="p">])</span>
<span class="k">raise</span> <span class="no">InvalidInput</span><span class="p">,</span> <span class="s1">'size must be 6'</span> <span class="k">unless</span> <span class="n">input</span><span class="p">.</span><span class="nf">size</span> <span class="o">==</span> <span class="mi">6</span>
<span class="k">raise</span> <span class="no">InvalidInput</span><span class="p">,</span> <span class="s2">"types don't match"</span> <span class="k">unless</span> <span class="n">input</span><span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:class</span><span class="p">)</span> <span class="o">==</span>
<span class="p">[</span><span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">Boolean</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">Boolean</span><span class="p">]</span>
</code></pre>
<p>As you can imagine, the validation took more effort without the existence of <code>Boolean</code>. Something like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">input</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span> <span class="o">==</span> <span class="kp">false</span> <span class="o">||</span> <span class="n">x</span> <span class="o">==</span> <span class="kp">true</span> <span class="p">?</span> <span class="ss">:boolean</span> <span class="p">:</span> <span class="n">x</span><span class="p">.</span><span class="nf">class</span> <span class="p">}</span> <span class="o">==</span>
<span class="p">[</span><span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="ss">:boolean</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="ss">:boolean</span><span class="p">]</span>
</code></pre>
</blockquote>
<p>There's a potential religious argument here about validating against the schema before/after deserialising. Pragmatically I understand that we have a JSON parser and we don't have a JSON validator, so it's much easier to validate-later. To that end, it's also really easy to monkey-patch your way to happiness:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">Boolean</span><span class="p">;</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">TrueClass</span><span class="p">;</span> <span class="kp">include</span> <span class="no">Boolean</span><span class="p">;</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">FalseClass</span><span class="p">;</span> <span class="kp">include</span> <span class="no">Boolean</span><span class="p">;</span> <span class="k">end</span>
<span class="p">[</span><span class="kp">true</span><span class="p">,</span> <span class="kp">false</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="kp">nil</span><span class="p">].</span><span class="nf">select</span> <span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="no">Boolean</span> <span class="o">===</span> <span class="n">x</span> <span class="p">}</span> <span class="c1">#=> [true, false]</span>
</code></pre>
<p>There's also the fact that just because JSON has a boolean type doesn't mean Ruby has to. Ruby has procs, but you can't serialise them into JSON.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611582016-11-01T00:04:33Zrrroybbbean (RRRoy BBBean)
<ul></ul><p>Joel on Software "Don't Let Architecture Astronauts Scare You" by Joel<br>
Spolsky <a href="http://www.joelonsoftware.com/articles/fog0000000018.html" class="external">http://www.joelonsoftware.com/articles/fog0000000018.html</a></p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611592016-11-01T01:51:12Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Rodrigo Rosenfeld Rosas wrote:</p>
<blockquote>
<p>Maybe something like:</p>
</blockquote>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Boolean</span> <span class="o">=</span> <span class="p">[</span><span class="kp">true</span><span class="p">,</span> <span class="kp">false</span><span class="p">]</span>
</code></pre>
<blockquote>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">input</span><span class="p">.</span><span class="nf">zip</span><span class="p">([</span><span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">Boolean</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">Boolean</span><span class="p">]).</span><span class="nf">all?</span><span class="p">{</span><span class="o">|</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span><span class="o">|</span> <span class="n">c</span> <span class="o">===</span> <span class="n">i</span> <span class="p">}</span>
</code></pre>
</blockquote> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611602016-11-01T02:59:10Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Samuel Williams wrote:</p>
<blockquote>
<blockquote>
<p>It's a choice by that library author. They are not classes but methods, there can be <code>Boolean</code> method in the library.</p>
</blockquote>
<p>Nobu, you are not looking deep enough.</p>
<p><a href="https://github.com/jeremyevans/sequel/blob/c39594dd35b3f8a8975b05be156ba664f1630804/lib/sequel/database/schema_generator.rb#L57-L61" class="external">https://github.com/jeremyevans/sequel/blob/c39594dd35b3f8a8975b05be156ba664f1630804/lib/sequel/database/schema_generator.rb#L57-L61</a></p>
</blockquote>
<p>It seems specific to the context, and should be defined there.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611692016-11-01T14:56:41Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Nobuyoshi Nakada wrote:</p>
<blockquote>
<p>Rodrigo Rosenfeld Rosas wrote:</p>
<blockquote>
<p>Maybe something like:</p>
</blockquote>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Boolean</span> <span class="o">=</span> <span class="p">[</span><span class="kp">true</span><span class="p">,</span> <span class="kp">false</span><span class="p">]</span>
</code></pre>
<blockquote>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">input</span><span class="p">.</span><span class="nf">zip</span><span class="p">([</span><span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">Boolean</span><span class="p">,</span> <span class="no">String</span><span class="p">,</span> <span class="no">Boolean</span><span class="p">]).</span><span class="nf">all?</span><span class="p">{</span><span class="o">|</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span><span class="o">|</span> <span class="n">c</span> <span class="o">===</span> <span class="n">i</span> <span class="p">}</span>
</code></pre>
</blockquote>
</blockquote>
<p>This doesn't seem to work as I just tested in irb: [true, false] === true => false</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611902016-11-03T04:23:32Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul></ul><blockquote>
<p>It seems specific to the context, and should be defined there.</p>
</blockquote>
<p>Yeah but it's not. 2,080,658 instances of code on GitHub disagree with you. It's not my personal opinion, it's tangible evidence. But what evidence do you have to support NOT adding <code>Boolean</code>? I can't think of any good reason why you shouldn't add it.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611922016-11-03T06:14:40Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Matz has explained the reasons.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=611932016-11-03T06:46:35Zphluid61 (Matthew Kerwin)matthew@kerwin.net.au
<ul></ul><p>Samuel Williams wrote:</p>
<blockquote>
<p>[...] But what evidence do you have to support NOT adding Boolean? I can't think of any good reason why you shouldn't add it.</p>
</blockquote>
<p>Ignoring most of the "bad" reasons in this thread, how about reiterating this one:</p>
<p>If Ruby core were to introduce <code>class Boolean</code>, a lot of those 2 million libraries you refer to would break, because they use <code>module Boolean</code> and <code>module</code> can't re-open a class.</p>
<ul>
<li><a href="https://github.com/search?q=language%3ARuby+%22module+Boolean%22&type=Code&utf8=%E2%9C%93" class="external">github search</a></li>
</ul>
<p>And who knows how many of the <code>class Boolean</code> peoples' code would also break if instance methods on their previously-safe classes were suddenly inherited by <code>TRUE</code> and <code>FALSE</code>?</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=612312016-11-04T12:37:35Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul></ul><p>Matthew, I ask you to find one of those examples that would break by introducing the following to core Ruby:</p>
<pre><code>if $VERBOSE and defined? Boolean
warn "Top level Boolean is deprecated, please update your code"
end
class Kernel::Boolean
end
class TrueClass < Kernel::Boolean
end
class FalseClass < Kernel::Boolean
end
</code></pre>
<p>Finally, if this really is the issue, then either 1/ put it inside <code>require 'boolean'</code> or 2/ release with ruby 3.0 - there are plenty of options, one does not need to be so pessimistic.</p>
<p>Personally, I find Matz argument about duck typing superficial. Because, this isn't a case of duck typing (abstraction) but set membership (is this either true or false). We already have useful checks for these things for Integer, Float, Numeric, String, etc. Why not Boolean? It's inconsistent.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=612432016-11-04T19:27:22Zduerst (Martin Dürst)duerst@it.aoyama.ac.jp
<ul></ul><p>Just a side question:</p>
<p>Samuel Williams wrote:</p>
<blockquote>
<p>class Kernel::Boolean<br>
end</p>
</blockquote>
<p>Why do you use Kernel::Boolean and not just Boolean?</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=612602016-11-04T22:42:12Zphluid61 (Matthew Kerwin)matthew@kerwin.net.au
<ul></ul><p>Samuel Williams wrote:</p>
<blockquote>
<p>Finally, if this really is the issue, then either 1/ put it inside <code>require 'boolean'</code> or 2/ release with ruby 3.0 - there are plenty of options, one does not need to be so pessimistic.</p>
</blockquote>
<p>It's just one of the issues, but it's the one backed by the same numbers you seem to think are the be-all and end-all. Anyone can munge code to not conflict with existing implementations. (<code>Kernel::Boolean</code>? Really?)</p>
<blockquote>
<p>Personally, I find Matz argument about duck typing superficial. Because, this isn't a case of duck typing (abstraction) but set membership (is this either true or false). We already have useful checks for these things for Integer, Float, Numeric, String, etc. Why not Boolean? It's inconsistent.</p>
</blockquote>
<p>It's because, as has already been stated, Integer#+ and Float#ceil are methods with implementations shared by all instances of those classes. There is no such method to define on Boolean. And if it's all about set membership, why is <code>NIL</code> not an instance of Boolean? (It is false) Why not all other objects? (They are true)</p>
<p>You are free to define whatever arbitrary sets you like, in whatever context it's appropriate. Put <code>"Y"</code> in the truthy set and <code>"N"</code> in the falsey, I don't care. But that doesn't mean you should push those (or any) arbitrary set memberships into the core.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=613922016-11-07T09:41:31Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul></ul><blockquote>
<p>Why do you use Kernel::Boolean and not just Boolean?</p>
</blockquote>
<p>Some gems define</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Boolean</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">TrueClass</span><span class="p">;</span> <span class="kp">include</span> <span class="no">Boolean</span><span class="p">;</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">FalseClass</span><span class="p">;</span> <span class="kp">include</span> <span class="no">Boolean</span><span class="p">;</span> <span class="k">end</span>
</code></pre>
<p>and some gems define:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">Boolean</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">TrueClass</span><span class="p">;</span> <span class="kp">include</span> <span class="no">Boolean</span><span class="p">;</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">FalseClass</span><span class="p">;</span> <span class="kp">include</span> <span class="no">Boolean</span><span class="p">;</span> <span class="k">end</span>
</code></pre>
<p>If we defined our own <code>class Boolean</code> it would conflict with users (not that many) who are defining <code>module Boolean</code>. So, instead we define <code>Kernel::Boolean</code>. It's just one option. A simple way of understanding that is that <code>Kernel</code> is kind of a top level scope for name resolution so it works just fine.</p>
<p>Personally I don't think it's important in this case, people defining <code>module Boolean</code> in the global scope are categorically doing the wrong thing, but that's just my opinion. However, the sample implantation I gave works, does not collide with any existing implementation and would be perfectly suitable going forward, where in Ruby 3 it could be renamed to <code>class Boolean</code> and all people have received sufficient warning.</p>
<blockquote>
<p>It's just one of the issues, but it's the one backed by the same numbers you seem to think are the be-all and end-all.</p>
</blockquote>
<p>The numbers are really just there to support the hypothesis that lots of people are working around the lack of <code>class Boolean</code> in core. The main issue here being a lack of consistency with other data types and specifically <code>x.is_a? Boolean</code>. Lot of people are doing this - there can be no disagreement here. It's an implementation detail whether methods are defined on <code>class Boolean</code> or <code>class TrueClass</code> and <code>class FalseClass</code> so Matz' argument does not resonate with me. I'm not arguing about implementation. I'm simply supporting moving into Ruby core what is already standard practice by 2 million examples.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=613972016-11-08T03:22:05Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p><code>Kernel</code> is included by <code>Object</code>, that is the toplevel namespace, they conflict.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Kernel::Boolean</span><span class="p">;</span> <span class="k">end</span>
<span class="k">module</span> <span class="nn">Boolean</span><span class="p">;</span> <span class="k">end</span> <span class="c1">#=> Boolean is not a module (TypeError)</span>
</code></pre> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=614782016-11-14T03:36:40Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul></ul><p>Nobu, thanks for that clarification. I was not aware of that.</p>
<p>If that's the only issue holding back this feature, I'm sure a workaround can be found that works appropriately.</p>
<p>It might be as simple as going with the more common option <code>class Boolean</code> and breaking when people define <code>module Boolean</code> in the global namespace, which in practice is very small percentage, and already represents a problem when people try to include code which does it both ways, and for which the preferred way is most certainly <code>class Boolean</code>.</p>
<p>Another option is to include in the standard library a <code>boolean.rb</code> which defines set semantics for what people are already doing. If you include this yourself, and other code breaks, it's your own fault.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=615102016-11-15T12:44:49Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul></ul><p>Samuel Williams wrote:</p>
<blockquote>
<p>If that's the only issue holding back this feature.</p>
</blockquote>
<p>Sadly no. The reason why this is not accepted is matz do not like the idea. You have to persuade him.</p>
<blockquote>
<p>Another option is to include in the standard library a <code>boolean.rb</code> which defines set semantics for what people are already doing. If you include this yourself, and other code breaks, it's your own fault.</p>
</blockquote>
<p>What's wrong with a gem, in that case? Raise of rubygems made it harder today than past to introduce a new standard library.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=631502017-02-23T16:49:57Zr.smitala (Radovan Smitala)
<ul></ul><p>You have in some cases true.</p>
<p>There should be some circumstances where implemented Boolean class should be problematic. But many of existed gems just reopen class and life goes on. Rails 5 isn't till now compatible with Ruby 2.4 with introduced Integer class.</p>
<p>I think we can looking on potential Boolean as Integer class. For integer doesn't matter which value represents, one condition is it should be whole number. From almost infinite negative to infinite positive number. But still it is Integer. Whole number is representation of type Integer.<br>
Boolean values are also described. They are represented by true and false. Object which can be just true or false is rightful, and is defined by Boolean type.</p>
<p>Still there should be fallback to FalseClass and TrueClass like for Bignum and Fixnum.</p>
<p>Boolean class is very handy. In coercions, in type checking, in validations, in nice looking and more understandable code, any many more examples.</p>
<p>Yukihiro Matsumoto wrote:</p>
<blockquote>
<p>Rejected for several reasons:</p>
<ul>
<li>many gems and libraries had already introduced <code>Boolean</code> class. I don't want to break them.</li>
<li>
<code>true</code> and <code>false</code> are the only representative of true-false values. In Ruby. <code>nil</code> and <code>false</code> are falsy values, and everything else is a true value. There's no meaning for having a superclass of <code>TrueClass</code> and <code>FalseClass</code> as <code>Boolean</code>.</li>
</ul>
<p>Matz.</p>
</blockquote> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=632682017-03-01T03:29:23Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul></ul><p>Radovan Smitala wrote:</p>
<blockquote>
<p>There should be some circumstances where implemented Boolean class should be problematic. But many of existed gems just reopen class and life goes on. Rails 5 isn't till now compatible with Ruby 2.4 with introduced Integer class.</p>
</blockquote>
<p>Kind of off topic maybe but can you tell us the Rails 5 story? I was not aware of such thing until now. If you want us to follow how Integer was integrated, there must be lessons to be learned.</p> Ruby master - Feature #12515: Create "Boolean" superclass of TrueClass / FalseClasshttps://redmine.ruby-lang.org/issues/12515?journal_id=632712017-03-01T07:00:00Zr.smitala (Radovan Smitala)
<ul></ul><p>Shyouhei Urabe wrote:</p>
<blockquote>
<p>Radovan Smitala wrote:</p>
<blockquote>
<p>There should be some circumstances where implemented Boolean class should be problematic. But many of existed gems just reopen class and life goes on. Rails 5 isn't till now compatible with Ruby 2.4 with introduced Integer class.</p>
</blockquote>
<p>Kind of off topic maybe but can you tell us the Rails 5 story? I was not aware of such thing until now. If you want us to follow how Integer was integrated, there must be lessons to be learned.</p>
</blockquote>
<p>Just deprecated warnings for Fixnum and Bignum :) And that is OK. Rails is biggest project/framework/tool in Ruby community. It takes some time to be fully compatible, not only for Integer addition, but all changes. 3 days before was released first public compatible version :)</p>