# Argument-oriented dot syntax?

**URL:** <https://discourse.julialang.org/t/argument-oriented-dot-syntax/21850>\
**Category:** Offtopic\
**Created:** [March 14, 2019, 3:12am UTC](https://discourse.julialang.org/t/argument-oriented-dot-syntax/21850 "2019-03-14T03:12:19Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![ettersi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ettersi/32/6829_2.png) [@ettersi](https://discourse.julialang.org/u/ettersi)\
**Post date:** [March 14, 2019, 3:12am UTC](https://discourse.julialang.org/t/argument-oriented-dot-syntax/21850/1 "2019-03-14T03:12:19Z")

</div>

Here’s an annoying question: wouldn’t things be easier if the dot-syntax for broadcasting focused on arguments rather than functions?

An example might explain the question better. Assume I have a function `lerp(x::Vector, y::Vector, xx::Number)` which takes in data points `x,y` and evaluates the linear interpolant at point `xx`. Soon enough I will want to evaluate the interpolant at a series of points `xx:Vector`, but `lerp.(x,y,xx)` won’t work because broadcast tries to zip the three vectors together. Instead, I have to use work-arounds like `lerp.((x,),(y,),xx)` or `(xx->lerp(x,y,xx)).(xx)`, both of which are a bit annoying. Imagine if I could write this as `lerp(x,y,.xx)` where the dot in front of `xx` indicates that I only want to broadcast over `xx`! This seems more natural and can easily be made backwards compatible by introducing the convention `f.(x,y) === f(.x,.y)`.

---

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [March 14, 2019, 6:33am UTC](https://discourse.julialang.org/t/argument-oriented-dot-syntax/21850/2 "2019-03-14T06:33:11Z")

</div>

I love the proposed syntax, but in terms of functionality, I though that `Ref` is what you want right now:

```julia
lerp.(Ref(x), Ref(y), xx)

```

I.e. you specify which arguments to freeze rather than broadcast.

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [March 14, 2019, 6:45am UTC](https://discourse.julialang.org/t/argument-oriented-dot-syntax/21850/3 "2019-03-14T06:45:25Z")

</div>

I discover recently the power of the broadcast function (the function behind the dot syntax); the problem can be expresed like this:

```julia
result= broadcast(z->lerp(x,y,z),xx)

```

is more verbose, but it makes clear what is constant and what is broadcasted

---

<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:** [March 14, 2019, 7:35am UTC](https://discourse.julialang.org/t/argument-oriented-dot-syntax/21850/4 "2019-03-14T07:35:21Z")

</div>

> [@ettersi](#):
>
> wouldn’t things be easier if the dot-syntax for broadcasting focused on arguments rather than functions?

The way I think about broadcast is that it is all about functions — eg [broadcast fusion](https://julialang.org/blog/2018/05/extensible-broadcast-fusion). _Not_ wanting to broadcast something is the special case, for which we have `Ref` & friends.

You could, of course, propose a syntax where

```julia
f(.x, .y, z)

```

is equivalent to the current

```julia
f.(x, y, Ref(z))

```

but you might as well just wait for sugar like [`&x`](https://github.com/JuliaLang/julia/pull/27608) that would make escaping much more compact (not that I am bothered about `Ref` that much, though, which is I guess why this PR was not rushed through).

---

<div class="post-metadata">

**Author:** ![ettersi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ettersi/32/6829_2.png) [@ettersi](https://discourse.julialang.org/u/ettersi)\
**Post date:** [March 14, 2019, 9:14am UTC](https://discourse.julialang.org/t/argument-oriented-dot-syntax/21850/5 "2019-03-14T09:14:25Z")

</div>

Maybe there’s space for both? It seems sometimes it’s more convenient to exclude arguments from broadcasting, sometimes it’s more convenient to include them.

Here’s another argument in favour of having both syntaxes: nested broadcasting. If I have a vector of vectors `v` and want to shift all of them by a constant `c`, I could write `..v + c`. Currently there’s no easy way to do this, afaik. I admit that currently this is a bit of a stretch of the concept, though.

---

<div class="post-metadata">

**Author:** ![ettersi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ettersi/32/6829_2.png) [@ettersi](https://discourse.julialang.org/u/ettersi)\
**Post date:** [March 14, 2019, 9:21am UTC](https://discourse.julialang.org/t/argument-oriented-dot-syntax/21850/6 "2019-03-14T09:21:22Z")

</div>

If we also have a “don’t-broadcast” operator like `Ref()`/`&`, you could even take this a notch further and let `..v + .&w` denote something like `broadcast((vi,wi)->broadcast(vii->vii+wi,vi),v,w)`, while `..v + &.w` denotes `broadcast(vi->broadcast((vii,wi)->vii+wi,vi,w),v)`.

---

<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:** [March 14, 2019, 10:09am UTC](https://discourse.julialang.org/t/argument-oriented-dot-syntax/21850/7 "2019-03-14T10:09:32Z")

</div>

> [@ettersi](#):
>
> Maybe there’s space for both? It seems sometimes it’s more convenient to exclude arguments from broadcasting, sometimes it’s more convenient to include them.

IMO functions with a too many (\> 3) arguments are code smell anyway, and if you find that you are excluding more arguments from broadcasting thnn you include maybe some refactoring is in order.

Eg if I end up doing

```julia
f.(x, Ref(y), z, Ref(w), u, Ref(parameters), Ref(κ))

```

then maybe I would benefit from

```julia
f(.x, y, .z, w, .u, parameters, κ)

```

but perhaps it would be better to take a coffee break, and refactor this into

```julia
f(Ref(CollectedParams(y, w, parameters, κ)), x, z, u)

```

---

<div class="post-metadata">

**Author:** ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)\
**Post date:** [March 15, 2019, 5:27am UTC](https://discourse.julialang.org/t/argument-oriented-dot-syntax/21850/8 "2019-03-15T05:27:40Z")

</div>

You are thinking of Package development where you _may_ have a point (I’m unconvinced) but Julia is not just for people like you who like to spend a lot of time structuring and fine-tuning their codes.

---

<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:** [March 15, 2019, 7:17am UTC](https://discourse.julialang.org/t/argument-oriented-dot-syntax/21850/9 "2019-03-15T07:17:16Z")

</div>

Good coding style benefits the programmer and the reader (may or may not coincide) in all contexts. When practiced regularly, it becomes a habit and takes less and less extra effort.

Too many function arguments are generally recognized as code smell. In an OO context, Robert C Martin (Clean Code, Chapter 3) writes:

> The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification—and then shouldn’t be used anyway.

but in Julia you get an extra argument because the above does not count the object.

In Julia, nothing precludes good code organization in scripts, because you essentially get the same tools for it as packages. Also, trivial scripts have a tendency to balloon into 2k-LOC monsters over time.
