# Why are numeric comparisions constrained to support only two args?

**URL:** <https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462>\
**Category:** New to Julia\
**Tags:** question, proposal\
**Created:** [August 19, 2017, 2:14pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462 "2017-08-19T14:14:36Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sighoya](https://avatars.discourse-cdn.com/v4/letter/s/a87d85/32.png) [@Sighoya](https://discourse.julialang.org/u/Sighoya)\
**Post date:** [August 19, 2017, 2:14pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/1 "2017-08-19T14:14:36Z")

</div>

Sadly, it is not possible to do:

op(1,2,3,4,5) where op \in {\<,\>,\<=,\>=,==,!=}

Why not add support for op to support varargs?

Beside that, why is && and || not a operator as the use of these two symbols as function is not allowed?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 19, 2017, 2:39pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/2 "2017-08-19T14:39:24Z")

</div>

Because those will not have the same semantics and `||`/`&&` are control flow syntax and not functions.

---

<div class="post-metadata">

**Author:** ![Sighoya](https://avatars.discourse-cdn.com/v4/letter/s/a87d85/32.png) [@Sighoya](https://discourse.julialang.org/u/Sighoya)\
**Post date:** [August 19, 2017, 4:33pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/3 "2017-08-19T16:33:00Z")

</div>

What mean not have the same semantics. In lisp (\< 1 2 3 4 5) is ok?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 19, 2017, 5:02pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/4 "2017-08-19T17:02:16Z")

</div>

1. This is not lisp
2. Both of them (chained comparison and `||`/`&&`) has shortcut evaluation semantics.

---

<div class="post-metadata">

**Author:** ![Sighoya](https://avatars.discourse-cdn.com/v4/letter/s/a87d85/32.png) [@Sighoya](https://discourse.julialang.org/u/Sighoya)\
**Post date:** [August 19, 2017, 5:08pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/5 "2017-08-19T17:08:30Z")

</div>

Can you explain that more. What you mean with shortcut semantics? Did you mean that if the first was false, then the other terms are not evaluated. This can be done in the varargs version \<(args…), too.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [August 19, 2017, 6:38pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/6 "2017-08-19T18:38:13Z")

</div>

> [@Sighoya](#):
>
> Did you mean that if the first was false, then the other terms are not evaluated. This can be done in the varargs version `<(args…)`, too.

This can’t be done with a varargs version, because function arguments are evaluated _before_ the function is called. This is why `&&` and `||` are not function calls, they are special syntactic constructs.

Note that you _can_ do `x < y < z < ...` and other “chained” comparisons in Julia.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 19, 2017, 7:55pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/7 "2017-08-19T19:55:28Z")

</div>

> [@stevengj](#):
>
> because function arguments are evaluated before the function is called

And this is why the

> [@yuyichao](#):
>
> This is not lisp

is very (/more) important.

---

<div class="post-metadata">

**Author:** ![Sighoya](https://avatars.discourse-cdn.com/v4/letter/s/a87d85/32.png) [@Sighoya](https://discourse.julialang.org/u/Sighoya)\
**Post date:** [August 19, 2017, 8:08pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/8 "2017-08-19T20:08:08Z")

</div>

Ok, Ithis is true for && and ||, but why the numeric comparision? Why we allow two args functions for \< but not many args as wee need?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 19, 2017, 8:15pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/9 "2017-08-19T20:15:02Z")

</div>

> [@Sighoya](#):
>
> but why the numeric comparision

Because

> [@yuyichao](#):
>
> Both of them (chained comparison and ||/&&) has shortcut evaluation semantics.

---

<div class="post-metadata">

**Author:** ![Sighoya](https://avatars.discourse-cdn.com/v4/letter/s/a87d85/32.png) [@Sighoya](https://discourse.julialang.org/u/Sighoya)\
**Post date:** [August 19, 2017, 8:17pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/10 "2017-08-19T20:17:37Z")

</div>

Again, what do you mean with shortcut evaluation semantics? Where is the contradiction

---

<div class="post-metadata">

**Author:** ![Sighoya](https://avatars.discourse-cdn.com/v4/letter/s/a87d85/32.png) [@Sighoya](https://discourse.julialang.org/u/Sighoya)\
**Post date:** [August 19, 2017, 8:24pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/11 "2017-08-19T20:24:51Z")

</div>

I will show you want I want and it works. I must only redefine \< with variable args by isless. Here is the code:  
function \<(x…)  
result=true  
for index in 1:length(x)-1  
result =result && isless(x[index],x[index+1])  
end  
result  
end

---

<div class="post-metadata">

**Author:** ![iamed2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamed2/32/215082_2.png) [@iamed2](https://discourse.julialang.org/u/iamed2)\
**Post date:** [August 19, 2017, 8:31pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/12 "2017-08-19T20:31:01Z")

</div>

I had a vararg comparison PR open here: [https://github.com/JuliaLang/julia/pull/22638](https://github.com/JuliaLang/julia/pull/22638)

It didn’t get much response.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 19, 2017, 9:30pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/13 "2017-08-19T21:30:27Z")

</div>

> [@Sighoya](#):
>
> Again, what do you mean with shortcut evaluation semantics? Where is the contradiction

What I mean is exactly what you said. I.e.

> [@Sighoya](#):
>
> if the first was false, then the other terms are not evaluated.

> [@Sighoya](#):
>
> I will show you want I want and it works. I must only redefine \< with variable args by isless. Here is the code:

`<` is a function so it works in that sense but it still doesn’t have the same semantics. All the function arguments are evaluated.

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [August 20, 2017, 5:22am UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/14 "2017-08-20T05:22:39Z")

</div>

Maybe an example will clarify. With chained `<`, we get lazy evaluation:

```julia
julia> f() = (println("f() is evaluated"); 2)
f (generic function with 1 method)

julia> 2 < 1 < f() # Will not call f()
false

```

Compare to using @Sighoya’s function from the above post

```julia
julia> <(2,1,f())
f() is evaluated
false

```

Here, `f()` is called before `<`, so it is evaluated even though 2 is not less than 1.

To make `<(x...)` work as expected (without making `<` into a special case) Julia would have to apply lazy evaluation to function arguments in general. This would be a really cool feature, but probably also really hard to implement and/or impossible to reconcile with dynamic dispatch.

---

<div class="post-metadata">

**Author:** ![Sighoya](https://avatars.discourse-cdn.com/v4/letter/s/a87d85/32.png) [@Sighoya](https://discourse.julialang.org/u/Sighoya)\
**Post date:** [August 20, 2017, 8:55am UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/15 "2017-08-20T08:55:40Z")

</div>

@Per, Thanks, I understand it yet. And to deliver a strict evaluatuion variant with varargs and a lazy evaluation variant with chaining is unidiomatic, right?

For me, it sucks that it cannot be used ala map(op, [1,2,3],[4,5,6],[7,8,9]) with op \in {\<,\>,\<=,\>=,==,!=,%unicode variants…%}. But fortunately, I can redefine these symbols, which is sadly not possible with &&, ||.

Did you plan to introduce “or” + “and” to use as alias for || and && in future?. Otherwise, I can write my own “and” and “or” variant accepting varargs.

The support of lazy evaluation would be good. Does julia have generators like in python. For instance that one could write something like that:  
\<(2,1 yield f())

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [August 20, 2017, 11:28am UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/16 "2017-08-20T11:28:19Z")

</div>

> [@Sighoya](#):
>
> And to deliver a strict evaluatuion variant with varargs and a lazy evaluation variant with chaining is unidiomatic, right?

I think it would be fine, honestly; I would be happy to merge some form of [RFC: Add vararg comparison functions by iamed2 · Pull Request #22638 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/22638)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 20, 2017, 11:54am UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/17 "2017-08-20T11:54:56Z")

</div>

> [@Sighoya](#):
>
> it sucks that it cannot be used ala map(op, [1,2,3],[4,5,6],[7,8,9]) with op \in {\<,\>,\<=,\>=,==,!=

Try something like

```julia
struct Chain{Tf}
    f::Tf
end

(c::Chain)(x, y) = c.f(x, y)

(c::Chain)(x, y, z...) = c(x, y) && c(y, z...)

map(Chain(<), [1,2,3],[4,5,6],[7,8,9])

```

---

<div class="post-metadata">

**Author:** ![Sighoya](https://avatars.discourse-cdn.com/v4/letter/s/a87d85/32.png) [@Sighoya](https://discourse.julialang.org/u/Sighoya)\
**Post date:** [August 20, 2017, 1:55pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/18 "2017-08-20T13:55:56Z")

</div>

@stevengj  
I’m lucky to see that someone else feels the same pain, thanks for this link

@Tamas_Papp  
Interesting… Does it cale for many lists? Because it seems to be a recursion variant.

Is there any reason why ||, && are control flows and not first class functions? Because numeric comparisions support shortcut circuit, too.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [August 20, 2017, 2:13pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/19 "2017-08-20T14:13:14Z")

</div>

> [@stevengj](#):
>
> I think it would be fine, honestly; I would be happy to merge some form of [RFC: Add vararg comparison functions by iamed2 · Pull Request #22638 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/22638)

It would be a little confusing since it won’t be the same as chained comparison. May not be a big deal assuming no one is going to write chained comparison as function calls…

> [@Sighoya](#):
>
> Is there any reason why ||, && are control flows and not first class functions? Because numeric comparisions support shortcut circuit, too.

Chained comparisons supports short circuit evaluation by **NOT** being functions so for the same reason `||`/`&&` aren’t functions.

---

<div class="post-metadata">

**Author:** ![Sighoya](https://avatars.discourse-cdn.com/v4/letter/s/a87d85/32.png) [@Sighoya](https://discourse.julialang.org/u/Sighoya)\
**Post date:** [August 20, 2017, 2:18pm UTC](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462/20 "2017-08-20T14:18:12Z")

</div>

@yuyichao  
But why support numeric comparision short circuit evaluation when they ARE functions.  
I mean 1\<0\<f() supports short circuit evaluation but \< is a function  
false && true && g() supports short circuit evaluation, but && is not a function.

[Next page](https://discourse.julialang.org/t/why-are-numeric-comparisions-constrained-to-support-only-two-args/5462.md?page=2)
