From: mame@... Date: 2020-10-19T02:34:00+00:00 Subject: [ruby-core:100424] [Ruby master Feature#17265] Add `Bool` module Issue #17265 has been updated by mame (Yusuke Endoh). Hi, I'd like to add the background. Currently, RBS provides `bool` type as an alias to `top` type (a union type of all types). The rationale is because any type is actually accepted in the context of condition expression of `if` and `while`. Some methods that accept a predicate block, such as `Enumerable#any?` and `#select`, also accept any type as the return value of the block. However, (almost) all methods that end with `?` returns `true | false`. For example, of we write `bool` as the return type of `Array#empty?`, it means that the method may return any type, which is a bit less precise. `true | false` is a bit redundant, so @marcandre wants to write `Bool` for it, But in RBS, a capitalized type corresponds to Ruby's class or module. So, to make the story simple, he is proposing adding a `Bool` module in Ruby side instead of RBS. --- Personally, I'm unsure if it is good or not to change Ruby for this. If his proposal is accepted, the type of `Enumerable#any?` will be: ``` def any? : { (Elem) -> bool } -> Bool ``` This looks cryptic to me. I think that the current statement (following) is good enough. ``` def any? : { (Elem) -> bool } -> true | false ``` BTW, @soutaro (the original author of RBS) is now thinking the redefinition of `bool` as an alias to `true | false`. Based on soutaro's idea, the type will be: ``` def any? : { (Elem) -> top } -> bool ``` In terms of documentation, it loses the information that the return value of the block is considered as a condition, but I'm okay for it, too. ---------------------------------------- Feature #17265: Add `Bool` module https://bugs.ruby-lang.org/issues/17265#change-88043 * Author: marcandre (Marc-Andre Lafortune) * Status: Open * Priority: Normal * Assignee: matz (Yukihiro Matsumoto) ---------------------------------------- 1-line Summary: `rbs` would benefit from the existence of common ancestor `Bool` for `TrueClass` and `FalseClass`. Detail: Matz: I am aware you rejected a similar request, but could we revisit this in light of RBS? One use case was for an easy way to check for `true` or `false` values, instead of simply for truthiness (e.g. for data transfer, strict argument checking, testing, etc.) I believe there's a new use case: `RBS` In `RBS`, the most used types like `String` and `Integer` have types for "string-like" and "integer-like" objects: `string` and `integer` (all lowercase). For example the signature for `Integer#>>` is: ``` def >>: (int) -> Integer ``` It accepts an `Integer` *or an object responding to `to_int`* (summarized by `int`) and returns an `Integer` (and never another class of object responding to `to_int` or not). There is a similar idea with boolean values, where a method may accept any object and will use it's truthiness, while returning `true | false`. For example one of the interface for `Enumerable#all?` should look like: ``` def all?: () { (Elem) -> bool } -> true | false ``` The user supplied block can return any value, and its truthiness (anything else than `nil` or `false`) will be used to determine the result of `all?`. That result will be `true | false`, and no other value. If RBS is to be popular, there will be *many* signatures for such predicates (in builtin Ruby, stdlib, any gems, applications, etc.). I feel the best option would be `Bool`, if this would be reflected in Ruby itself. Proposal: a new global module called `Bool`, without any method of constant, included in `TrueClass` and `FalseClass`. Following reasons for rejection were given at the time: > many gems and libraries had already introduced Boolean class. I don't want to break them. I looked and found the [`bool` gem](https://rubygems.org/gems/bool) that defines a `Bool` module. My proposal is compatible. In any case, this gem looks abandoned, the author Aslak Helles�y doesn't have the code on github, the gem has had 7000 downloads in the past 6 years and [has no public reverse dependency](https://rubygems.org/gems/bool/reverse_dependencies). It also fails to install on my machine. I am not aware of incompatibilities. > `true` and `false` are the only representative of true-false values. In Ruby. `nil` and `false` are falsy values, and everything else is a true value. There's no meaning for having a superclass of `TrueClass` and `FalseClass` as `Boolean`. The proposal is exactly to be able to easily write about this duality of `Bool` as having only `true` and `false` as members, and every Ruby object as being implicitly convertible as being truthy or falsy (`bool` in RBS). Discussion in RBS: * https://github.com/ruby/rbs/issues/133 Previous feature requests for `Boolean`: * https://bugs.ruby-lang.org/issues/14224 * https://bugs.ruby-lang.org/issues/12515 -- https://bugs.ruby-lang.org/ Unsubscribe: