From: shevegen@... Date: 2020-10-22T10:41:57+00:00 Subject: [ruby-core:100498] [Ruby master Feature#17265] Add `Bool` module Issue #17265 has been updated by shevegen (Robert A. Heiler). I tried to make a shorter summary of my thoughts here, so just three points - hopefully that makes it easier to read: (1) Most of the discussion, I think, happened at https://github.com/ruby/rbs/issues/133 - if I then understand the discussion correctly then it would mean that ruby would have to add "module Bool" or "module Boolean". (2) One slight problem I see with that is that a use case originating (mostly) from RBS, even if it makes sense from the point of view of RBS, would potentially effect change in MRI ruby. I don't have a strong opposing opinion per se, but I think it would be better if the use case would be from MRI directly, rather than the other way around. See also headius' comment in another issue about other implementations potentially affecting MRI via tests/specifications. I am not involved in test/specs but I understood what headius meant here. This is one reason why I think it should be considered carefully whether change is really necessary in this regard. Keep also in mind that when a "module Bool / Boolean" exists in ruby, new users may ask how this should then be used, and it may be a bit complicated if the explanation is "because RBS uses it", even more so if these users may not need or use RBS (not everyone will use types; some may but others may not). (3) I know way too little about the internals (admittedly I am not clever enough for high level C, and I am not even kidding here), but if the use case is primarily originating from RBS itself, could there be not another, indirect solution? For example, rather than requiring a change in MRI, could there not be some kind of meta-VM instead, that could be targeted? A bit like rubocop too, perhaps, for RBS? That way people could set it up for their own projects, adjust it as needed, and "simulate" as if a boolean "type" were to exist, without MRI needing to add a module, sort of where you just were to "simulate" that a boolean value exists. Again, I am not sure if this makes any sense what I write, but perhaps it would be better to wait some time, see how RBS shapes up, how the use cases may change, and then re-evaluate in say, two years or so. There are already quite a lot of changes if we look at the ruby-jit, ractor and so forth - it may be more clear how RBS may have to change (or effect change) in a little while. ---------------------------------------- Feature #17265: Add `Bool` module https://bugs.ruby-lang.org/issues/17265#change-88118 * 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: