Issue #14724 has been updated by Student (Nathan Zook).


As a mathematician, this suggestion really has my attention.

First, I almost never write a <= b && b < c.  What I do write is some form of (a...c) === b.  There are two reasons for this.  In the first case, b is being repeated, and we want to avoid this if we can do so without compromising clarity.  Secondly, and more importantly, because b is being evaluated twice, the expression might evaluate "inconsistently" if b has a time dependency.  Note:  one of the examples given DOES have a time dependency, although it is between a and c.  This is a real problem which regularly crops up in production code.

Second, I must object strenuously to the suggestion that a < b < c become valid but a < b > c < d < e < f > g not.  That would be a serious inconsistency from the standpoint of someone who makes regular use of such notation, and also a violation of the description of "chaining" operators.

Third, the suggested implementation (to treat a < b < c as (a < b) && (b < c)) is simply wrong as it creates an invisible time dependency on b that does not exist in the mind of the average programmer.  If this suggestion is to be implemented, it needs to be implemented as follows:
1) evaluate "a", and store value in x1.
2) evaluate "b", and store value in x2.
3) return false unless x1 < x2.
4) return x2 < c.

Fourth, the previously-mentioned ambiguity of a < b == c created by chaining is a significant problem.  While == does not mean "<= and >=", that is a subtly that is going to catch people up.  While I agree that the only solution, unless we are just trying to break user code, is to exclude == from such changes, it is going to surprise people who start using a < b < c-type constructs.

Fifth, Ruby allows us to define operators on classes, and even to overwrite them on core classes.  The suggested change has the potential to create nasty breaks in existing code.  If implemented, I would urge that it be delayed until Ruby 3, but announced immediately so that the community is able to prepare for it.

Also, Shell might be used more in private code than in published code.  I'm pretty sure I've used it professionally.


On balance, I don't really like this idea.  AFAIK, we only have one tertiary operator right now, ?:, and nothing higher.  The only consistent implementation would create an n-ary operator.  While this would certainly be "cool", the common use cases are in fact adequately covered with range operators.

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

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