# Dot notation

**URL:** https://discourse.julialang.org/t/dot-notation/48776
**Category:** General Usage
**Created:** [October 21, 2020, 8:12pm UTC](https://discourse.julialang.org/t/dot-notation/48776 "2020-10-21T20:12:52Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![rcnlee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rcnlee/32/4107_2.png) [@rcnlee](https://discourse.julialang.org/u/rcnlee)
#### Post date: [October 21, 2020, 8:12pm UTC](https://discourse.julialang.org/t/dot-notation/48776/1 "2020-10-21T20:12:52Z")

</div>

Hello,

I’m trying to understand the internals of what happens when using the dot notation.

There seems to be a few ways to make the call:

```julia
x = [1,2,3]; y=[0,2,4]
x .<= y #method 1
.<=(x,y) #method 2
(<=).(x,y) #method 3

```

What is happening under the hood in each of these methods? Are they all remapped to a broadcast call eventually?

I see that `.<=` does not exist as a function, but `<=` does. So I suspect that somewhere it is being parsed and reissued as a different call. Where (in which source file) does this remapping actually occur?

When I look at the AST, I see that method 1 and method 2 are the same, whereas method 3 is different. But I haven’t been able to trace it further.

Any insights would be appreciated. Thanks!

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [October 21, 2020, 8:18pm UTC](https://discourse.julialang.org/t/dot-notation/48776/2 "2020-10-21T20:18:29Z")

</div>

You should probably read through [More Dots: Syntactic Loop Fusion in Julia](https://julialang.org/blog/2017/01/moredots/). it’s a really good overview of broadcasting in Julia.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [October 21, 2020, 8:30pm UTC](https://discourse.julialang.org/t/dot-notation/48776/3 "2020-10-21T20:30:51Z")

</div>

They all get lowered to the same thing:

```julia
CodeInfo(
1 ─ %1 = Base.broadcasted(Main.:<=, x, y)
│ %2 = Base.materialize(%1)
└── return %2
)

```

`<=` is just a function so `x <= y` is identical to `<=(x, y)`. Adding the broadcasting dot before an operator, `.op`, or after, `(op).` are also the same.

---

<div class="post-metadata">

### Author: ![rcnlee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rcnlee/32/4107_2.png) [@rcnlee](https://discourse.julialang.org/u/rcnlee)
#### Post date: [October 21, 2020, 11:39pm UTC](https://discourse.julialang.org/t/dot-notation/48776/4 "2020-10-21T23:39:57Z")

</div>

Thanks folks! The post mentions that “the compiler notices these dots at _parse time_ (or technically at “lowering” time, but in any case long before it knows the types of the variables etc.), and transforms them into calls to `broadcast` .” I was looking for exactly where this translation to broadcast calls happens and I couldn’t find it in Base. I think it happens either in the Lisp code (julia-parser.scm or julia-syntax.scm) or in the C code (interpreter.c) or a combination.

I believe there is a slight difference in how the methods are handled in the compiler. Method 1 (infix) and method 2 (dotted symbol) seem to get handled in julia-parser.scm as special symbols “prec-comparison”; whereas method 3 (dotted function) seem to get handled by dot fusion in julia-syntax.scm around line 1752.

---

<div class="post-metadata">

### Author: ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)
#### Post date: [October 22, 2020, 12:10am UTC](https://discourse.julialang.org/t/dot-notation/48776/5 "2020-10-22T00:10:20Z")

</div>

> [@rcnlee](#):
>
> Method 1 (infix) and method 2 (dotted symbol) seem to get handled in julia-parser.scm as special symbols “prec-comparison”; whereas method 3 (dotted function) seem to get handled by dot fusion in julia-syntax.scm around line 1752.

That’s not quite the whole story.  
Regarding your examples 1 and 2: To the parser, `.=>` is no different from any other infix operator, which just happens to have the same precedence as `=>`. All the `add-dots` function you see at the top of `julia-syntax.jl` does, is add both `op` and `.op` to the parser’s list of valid operators. The parser doesn’t have any clue that these are broadcasted calls, to it, they are just regular call expressions.  
`(=>).(a, b)` is parsed as `(|.| => (tuple a b))`, which is pretty much treated the same as getproperty, like `a.b` from the parser’s perspective.  
Since just a couple of days ago on master, there’s also a 4th case, namely `(.=>)(a, b)`, because to enable standalone `.op` syntax to represent the broadcasted version operators as in `map(.*, a, b)`, this is parsed as `(call (|.| =>) a b)`, i.e. a function call expression to the expression `(|.| =>)`.  
This means, that none of the actually interesting stuff about broadcasting syntax, like broadcast fusion or fused inplace broadcasts is actually handled by the parser, which is exactly as it should be, since the parser’s job is to just produce a tree representation of directly what you wrote and not really try to interpret what this means functionally. All of the cases above are then handled in `expand-fuse-broadcast` in `julia-syntax.jl`, as you wrote above, to actually implement all the broadcasting semantics and lowering to the proper Base functions in `Base.Broadcast`.

---

<div class="post-metadata">

### Author: ![rcnlee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rcnlee/32/4107_2.png) [@rcnlee](https://discourse.julialang.org/u/rcnlee)
#### Post date: [October 22, 2020, 4:38pm UTC](https://discourse.julialang.org/t/dot-notation/48776/6 "2020-10-22T16:38:32Z")

</div>

Yes, right, thanks for the info! I guess the part that had me confused was why they had different intermediate `Expr` representations and where things get merged back together to a broadcast call. I think I understand now. Method 1 and method 2 are parsed (by julia-parser.scm) as dotted symbols and the expression that is produced has a head of `.<=`. Method 3 is parsed as a broadcast function call and the expression that is produced has a head of `.`. Both of these cases are handled in `expand-fuse-broadcast` in julia-syntax.scm as you said. Method 1 and 2 are treated by `dotop-named` (operators that begin with a dot), which is defined in ast.scm. Method 3 is treated by `dot-to-fuse`. In the end, all cases are converted to `broadcasted` and `broadcasted_kwsyntax` calls, which are implemented in Base.Broadcast as you said.

Thank you everyone!
