Despite being equal, they behave differently:

```
julia> sqrt.([4, 9])
2-element Vector{Float64}:
2.0
3.0
julia> sqrt == √
true
julia> √.([4, 9])
ERROR: syntax: invalid identifier name "."
Stacktrace:
[1] top-level scope
@ none:1
```

Despite being equal, they behave differently:

```
julia> sqrt.([4, 9])
2-element Vector{Float64}:
2.0
3.0
julia> sqrt == √
true
julia> √.([4, 9])
ERROR: syntax: invalid identifier name "."
Stacktrace:
[1] top-level scope
@ none:1
```

2 Likes

This is just a parsing thing. You want

```
julia> (√).([4, 9])
2-element Vector{Float64}:
2.0
3.0
```

8 Likes

Then where can I read Julia’s parsing implementation? I looked around in julia/src/ast.c but I’m not familiar with this part of code and can not find the precise location which is in cause.

I couldn’t tell you the cause either. But I do know that for unary or binary operators, to broadcast them you generally need to wrap them in parentheses.

2 Likes

Yeah, strangely with infix operators the `.`

goes in front of the operator:

```
julia> .√([4, 9])
2-element Vector{Float64}:
2.0
3.0
```

It’s like the binary `.+`

and `.*`

. That said, given that this is a syntax error… I wonder if we couldn’t support either placement.

7 Likes

I think the ship has sailed on that. After 1.6, `.+`

and `.*`

are defined as `Base.Broadcast.BroadcastFunction(+)`

. Actually so is square root

```
julia> .√
Base.Broadcast.BroadcastFunction(sqrt)
```

I don’t see why that changes anything. `.√([3,4])`

doesn’t actually create a `BroadcastFunction`

. I’m just saying maybe we could also support `√.([3,4])`

like a normal function named `√`

?

3 Likes

Just to be clear, the reason they behave differently is that `sqrt`

is an ordinary function name while `√`

is a **unary operator**.

That means, for example, that you can apply `√`

without parentheses:

```
julia> √2
1.4142135623730951
```

and like all operators in Julia it is “vectorized” by putting a `.`

*before* the operator (a convention adopted from Matlab):

```
julia> .√[4,9]
2-element Vector{Float64}:
2.0
3.0
```

I agree with @mbauman that, *if* you use a binary/unary operator `OP`

with parens, as `OP(...)`

, then it would not be crazy to allow `OP.(...)`

as an alternative vectorization syntax similar to ordinary functions. This doesn’t seem like it would be breaking since it is currently a syntax error.

16 Likes