Issue #14724 has been updated by gotoken (Kentaro Goto).


A Eregon (Benoit Daloze) wrote:
> > 1. if a non-boolean is returned, treats the rest of chain in the compatible manner.
> > 2. detects only same direction operators, e.g., `a < b <= c` is a chain, but `a < b >= c` is not a chain.
> > 3. accepts incompatibility.
> > 
> > I hope 1 if it is possible.
> 
> I think (1) is too magic and not consistent.
> What if < could return legitimately a boolean or something else? Then a < b <= c would become unpredictable.
> Every conversion to boolean in Ruby follows !(v.equal? false || v.equal? nil),
> it would be bad to break that by e.g. treating nil completely differently than false in such a case.

I don't think (1) is too magic but I agree (1) is magic. Probably there are only two kinds of `<`s  in this world: returns boolean and returns non-boolean. Potentially returning both depending on some conditions is not illegal but I could not imagine such use cases. About `nil` I think it is better to treat `nil` as same as false because `nil.<` is undefined and `(a < b) < c` is not obviously intended if `a < b` is `nil`.

Nevertheless, I would change my thought if this unpredictability causes performance decrement of optimizations seriously.

> (2) makes more sense to me, although it will likely still be occasionally surprising (but hopefully rarely).

Maybe so. A weakness of this option is that there some strange incompatible cases may use `a < b < c` in their special manner. They will not be saved by this option.

> (3) seems fine too as I would guess extremely few libraries use comparison operators like that.
> At least then everything is consistent, and we only need to patch the little-used Shell class.

Thank you for positive comment. I thought so too but I found another knid of incompatible library today. That is Rucas, a computer algebra system (looks prototype level) https://github.com/jdleesmiller/rucas

This interesting project seems stopped long years however Rucas can represent chained inequalities. One can with Rucas (and facets 2.8.1) do:

```ruby
require "rucas"
include Rucas::Symbolic
var :a
var :b
var :c

formula = a < b < c

p form 
#=> #<struct Rucas::LTExpr op=:<, lhs=#<struct Rucas::LTExpr op=:<, lhs=#<struct Rucas::VarExpr name=:a>, rhs=#<struct Rucas::VarExpr name=:b>>, rhs=#<struct Rucas::VarExpr name=:c>>

puts formula
#=> a < b < c
```

I often have scenes that I would like to write `a < b < c` in practical code and wrote this request but I don't want to put obstacle to such DSL if it is possible.

----------------------------------------
Feature #14724: chains of inequalities
https://bugs.ruby-lang.org/issues/14724#change-71827

* Author: gotoken (Kentaro Goto)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version: 
----------------------------------------
In mathematics, chain of inequations is a shorthand notation for the conjunction of several inequations involving common expressions. 

For example, `a < b <= c` for `a < b && b <= c`

Chain notation makes code clearer, in particular, long common expression cases will be so. E.g., 

```
cur.to_i - 2 <= timeval.tv_sec <= cur.to_i
```

is easier to read than

```
cur.to_i - 2 <= timeval.tv_sec && timeval.tv_sec <= cur.to_i
```

because in the latter case we have to verify whether `timeval.tv_sec` is common or not by eyes.

Current syntax allows but redefining builtin methods are considered not practical. So here I request as a new syntax for the chains.


### Use cases (applicable conjunctions)

lib/matrix.rb:
```ruby
    unless 0 <= column && column < column_count
```

lib/time.rb documents:
```ruby
    # block.  For example:
    #
    #     Time.parse(...) {|y| 0 <= y && y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}
```

spec/ruby/optional/capi/bignum_spec.rb:
```ruby
  raise "Bignum#coerce returned Fixnum" if fixnum_min <= n && n <= fixnum_max
```

test/fiddle/test_import.rb:
```ruby
        assert(cur.to_i - 2 <= timeval.tv_sec && timeval.tv_sec <= cur.to_i)
```

tool/jisx0208.rb:
```ruby
        unless 0x8140 <= sjis && sjis <= 0xFCFC
```




-- 
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>