Error I don't understand involving infix operator

So, I defined a function like so (using \parallel):

julia> ∥(a,b) = 1/(1/a+1/b)
∥ (generic function with 1 method)

julia> ∥(10,10)
5.0

julia> 10∥10
5.0

julia> 10∥10∥10
ERROR: TypeError: non-boolean (Float64) used in boolean context
Stacktrace:
 [1] top-level scope at REPL[40]:1

julia> (10∥10)∥10
3.333333333333333

What explains the TypeError? Thanks!

1 Like

The problem is that this gets lowered as ||(a,b,c), which gets dispatched to Boolean or.

Hi @Oscar_Smith, how do you know that? @code_lowered doesn’t seem to be helpful here.

This works

julia> @code_lowered (10∥10)∥10
CodeInfo(
1 ─ %1 = 1 / a
│   %2 = 1 / b
│   %3 = %1 + %2
│   %4 = 1 / %3
└──      return %4
)

but this doesn’t:

julia> ∥(a,b,c) = 1/(1/a+1/b+1/c)
∥ (generic function with 2 methods)

julia> @code_lowered 10∥10∥10
ERROR: expression is not a function call, or is too complex for @code_lowered to analyze; break it down to simpler parts if possible
Stacktrace:
 [1] error(::String) at .\error.jl:33
 [2] top-level scope at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.2\InteractiveUtils\src\macros.jl:151

Nor does defining it with three arguments resolve the original error:

julia> 10∥10∥10
ERROR: TypeError: non-boolean (Float64) used in boolean context
Stacktrace:
 [1] top-level scope at REPL[53]:1

so I’m not sure that it really calls ∥(10,10,10).

Also, please note that I named the function which is a unicode character entered by \parallel followed by tab, not || (two pipe characters in a row).

Oh, oops, misread. Not sure what’s happening then.

I don’t know the answer, but have you tried with some other infix operator? Would be good to know if it’s a general problem with the way it’s defined or if there’s something special about \parallel

The problem is that the symbol (U+2225) is parsed as a comparison operator, like == or >=, so a ∥ b ∥ c gets parsed as a “chained comparison” and is essentially a ∥ b && b ∥ c, just as a == b == c is equivalent to a == b && b == c.

The reason it is parsed as a comparison operator is that the official Unicode meaning of the symbol is boolean: PARALLEL TO.

You are using because you want the formula for adding resistors in parallel, I’m guessing. But I would use some other symbol, e.g. (\doubleplus tab) or +ᵣ (+\_r tab), both of which have + precedence.

1 Like

Thank you.

I think I’ve found where that stuff lives (julia-parser.scm) although I don’t find either \parallel or \doubleplus in that file. Is this somewhere in the docs?

The tab completions are not part of the language or the parser, they are “just” a feature of the REPL (and many editors etcetera). All of the tab completions are listed in the manual, and you can also get it from the REPL help:

help?> ⧺
"⧺" can be typed by \doubleplus<tab>
1 Like

I’m sorry. I understand the \parallel followed by tab feature. What I was asking is where can I find information about infix operators and their precedences and categories (e.g. times, plus, comparison) in the docs.

Currently, the manual just refers you julia-parser.scm. Both and are indeed in that file.

Well now they are! :thinking: I apparently did something wrong when searching for them earlier - sorry about that and thanks for the help!

Hi Klaff,
I want to note that (10||10)||10 would not be the same as 10||10||10 . A binary operator for the 2nd expression which failed is not sufficient since it should evalutate to 1/(1/10 + 1/10 + 1/10) . You’d need a n-ary operator like the ‘+’ (n-ary operators are still rare in Julia AFAIK, there was a discussion about it on GitHub to use n-ariness with other operators). Besides the parallel-to operator there is another mathematics operator which I know is n-ary: the cartesian product. I don’t know if the cartesian product is defined as default in Julia but if then it could be worth considering n-ariness for it. It could allow to generate vectors with simple syntax.