Issue #12134 has been updated by Martin Dürst.


Tsuyoshi Sawada wrote:

> Please do not confuse this with the common proposal to map booleans to integers, particularly `true.to_i # => 1` and `false.to_i # => 0`. That is arbitrary, and does not make sense.

In absolute terms, it is arbitrary. But it's the most widely used mapping, and therefore would make much more sense than any other mapping.

> In fact, my proposal goes against such proposal (under the proposal to map booleans, `true.to_i <=> false.to_i` translates to `1 <=> 0 # => 1`, which goes against my proposal `true <=> false # => 01`).

As far as I can remember, it's customary to define true being greater than false. I think this can be explained by the fact that true (something) is easily considered greater than false (nothing).

I think it's worth to check other programming languages. In Python, for example:
~~~PYTHON
>>> True > False
True
~~~

Your specific example can still easily be written as:
~~~RUBY
[7, 6, 5, 4, 3, 2, 1].sort_by{|e| [not Prime.prime?(e), e]} # => [2, 3, 5, 7, 1, 4, 6]
~~~

----------------------------------------
Feature #12134: Comparison between `true` and `false`
https://bugs.ruby-lang.org/issues/12134#change-57331

* Author: Tsuyoshi Sawada
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
There are some needs to sort elements depending on whether they satisfy certain condition expressed as a predicate. For example, to place prime numbers before others:

~~~RUBY
require "prime"
[7, 6, 5, 4, 3, 2, 1].sort_by{|e| Prime.prime?(e) ? 0 : 1} # => [7, 5, 3, 2, 6, 4, 1]
~~~

or to do such sort with the secondary condition to sort by the size:

~~~RUBY
[7, 6, 5, 4, 3, 2, 1].sort_by{|e| [Prime.prime?(e) ? 0 : 1, e]} # => [2, 3, 5, 7, 1, 4, 6]
~~~

Here, the temporal assignment of magic numbers `0` and `1` is ad hoc, but ordering between `true` and `false` makes sense. And given that there are `if` construction (which is unmarked case compared to the `unless` construction) and the ternary operator, in which the truthy branch is placed before the falsy branch, I think it makes sense to assume an inherent ordering of `true` being placed before `false`.

So I propose comparison between `true` and `false`:

~~~RUBY
true <=> false # => -1
false <=> true # => 1
~~~

Using this, the cases above can be written more directly as:

~~~RUBY
[7, 6, 5, 4, 3, 2, 1].sort_by{|e| Prime.prime?(e)} # => [7, 5, 3, 2, 6, 4, 1]
[7, 6, 5, 4, 3, 2, 1].sort_by{|e| [Prime.prime?(e), e]} # => [2, 3, 5, 7, 1, 4, 6]
~~~

---

Please do not confuse this with the common proposal to map booleans to integers, particularly `true.to_i # => 1` and `false.to_i # => 0`. That is arbitrary, and does not make sense. In fact, my proposal goes against such proposal (under the proposal to map booleans, `true.to_i <=> false.to_i` translates to `1 <=> 0 # => 1`, which goes against my proposal `true <=> false # => 01`).



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

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