# Appending \`!\` to names of callable objects (functors) that modify their argument?

**URL:** https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343
**Category:** General Usage
**Tags:** question, metaprogramming
**Created:** [November 28, 2017, 1:28am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343 "2017-11-28T01:28:09Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![Sleort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sleort/32/4875_2.png) [@Sleort](https://discourse.julialang.org/u/Sleort)
#### Post date: [November 28, 2017, 1:28am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343/1 "2017-11-28T01:28:09Z")

</div>

Suppose I have defined

```julia
struct MyFunctor
    x::Int
end

```

and I want to make `MyFunctor` objects callable in two ways, where one method modify the argument, say

```julia
(f::MyFunctor)(y) = y + f.x
(f::MyFunctor)(a, y) = push!(a, f(y))

```

Now

```julia
f = MyFunctor(2)
f(3) # -> 5
a = [1, 2]; f(a,3) #a == [1, 2, 5]

```

works fine. However, the style guide says “[Append `!` to names of functions that modify their arguments](https://docs.julialang.org/en/latest/manual/style-guide/#Append-!-to-names-of-functions-that-modify-their-arguments-1)”, so my second method should ideally be named `f!` instead of `f`. Is there a nice (standard?) way of accomplishing this without having to (manually) rename the callable object? In other words, it would be nice to automatically have the second method named `f!` when I define `f = MyFunctor(2)`.

I’m sure there is a metaprogramming way of accomplishing this. Unfortunately I’m not sure of it’s (recommended) direction…

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [November 28, 2017, 4:47am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343/2 "2017-11-28T04:47:14Z")

</div>

My personal opinion on this is that functor objects shouldn’t modify the outside world. What is your application? Why do you need to have functor objects modifying external variables?

---

<div class="post-metadata">

### Author: ![Sleort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sleort/32/4875_2.png) [@Sleort](https://discourse.julialang.org/u/Sleort)
#### Post date: [November 28, 2017, 5:33am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343/3 "2017-11-28T05:33:05Z")

</div>

Could you elaborate? I do not see why - on a principal basis - a functor object should be more restricted than any other function. If we can define `rand` and `rand!`, why not `f::MyFunctor` and `f!::MyFunctor`? I agree that it would be bad in many cases (like my silly, minimal example), but in _all_?

To be a little more specific: I’m implementing a [reweighting](http://www.sklogwiki.org/SklogWiki/index.php/Histogram_reweighting) package. There I construct a `Reweights` object from a set of input data (obtained from Monte Carlo sampling), i.e. `rw = Reweights(somedata)`. (And by the way, the construction of the object may be expensive, so I would like to initialize it once per data set.) From that object I want to be able to calculate a set of weights (stored in a `Vector`) at some parameter of choice `p`, like `weights = rw(p)`. However, since I would like to repeatedly calculate `weights` for different `p`’s, I thought it would be nice to be able to calculate `weights` in-place (non-allocating) if desired, like `rw!(weights, p)`. It of course works fine with `rw(weights, p)`, but then the notation is not following the style-guide…

Sure, it is possible to redesign my program and use a couple of functions like `make_weights(rwo::ReweightDataObject, p)` and `make_weights!(weights, rwo::ReweightDataObject, p)` instead, but that looks less elegant to me…

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [November 28, 2017, 5:47am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343/4 "2017-11-28T05:47:28Z")

</div>

I kind of like your second suggestion, it looks more elegant to me to have a verb in the function like `make_weights` and `make_weights!` instead of a functor object. Multiple dispatch and functional programming play very well together, and using active verbs in the function names makes things extremely clear in my opinion. As you said, this is a matter of taste.

EDIT: you can also rename your function `make_weights` to something like `evaluate` if you want something more elegant:

```julia
rw = ReweightObj(data)

weights = evaluate(rw, p)
evaluate!(rw, p, weights) # no allocation

```

---

<div class="post-metadata">

### Author: ![Sleort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sleort/32/4875_2.png) [@Sleort](https://discourse.julialang.org/u/Sleort)
#### Post date: [November 28, 2017, 6:12am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343/5 "2017-11-28T06:12:19Z")

</div>

So are there some guidelines on when one should use callable objects `f(x)` and when one should use the `evaluate(f, x)` structure? I mean, my `Reweights` is conceptually not that different from, say, [the polynomial example in the manual](https://docs.julialang.org/en/stable/manual/methods/#Function-like-objects-1) (or the huge functions/functors people are throwing around when doing [machine learning](https://fluxml.github.io/Flux.jl/stable/models/basics.html))…

(I agree that `evaluate` is more elegant than `make_weights` 🙂 )

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [November 28, 2017, 6:20am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343/6 "2017-11-28T06:20:03Z")

</div>

That is a good question, I will defer it to someone else, didn’t thought about it enough. 🙂

As a super simple rule of thumb, I only consider functor objects for concepts that somehow have a one-to-one correspondence to a mathematical concept. Like the example with polynomials you pointed out. Other than that, the `evaluate` approach is more clear in my opinion. If was using a package like yours for example about reweighting, I would never think of a weight as a function in the mathematical sense.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [November 28, 2017, 6:28am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343/7 "2017-11-28T06:28:34Z")

</div>

Another current limitation of functor objects is that you can’t specify the interface in the abstract level:

```julia
abstract type Functor end

# try to specify interface
(f::Functor)(x) = error("not implemented") # this won't compile

```

and I always take that into account before I commit to functor objects. It shouldn’t be a limitation in future versions of Julia though.

---

<div class="post-metadata">

### Author: ![Sleort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sleort/32/4875_2.png) [@Sleort](https://discourse.julialang.org/u/Sleort)
#### Post date: [November 28, 2017, 6:54am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343/8 "2017-11-28T06:54:54Z")

</div>

Good points. (Although what constitutes a “one-to-one correspondence to a mathematical concept” is not very clear to me. One (wo)man’s polynomial is another (wo)man’s point in a Hilbert space… )

I guess I’ll migrate my code to an `evaluate` style, then 🙂

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [November 28, 2017, 6:56am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343/9 "2017-11-28T06:56:59Z")

</div>

> [@Sleort](#):
>
> One (wo)man’s polynomial is another (wo)man’s point in a Hilbert space…

We talk about both as functions still 🙂

---

<div class="post-metadata">

### Author: ![Sleort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sleort/32/4875_2.png) [@Sleort](https://discourse.julialang.org/u/Sleort)
#### Post date: [November 28, 2017, 7:10am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343/10 "2017-11-28T07:10:45Z")

</div>

My point is that it depends on ones perspective: Do we focus on the functions (operators/maps) themselves, or the elements they map to? Both perspectives are perfectly valid (both for polynomials and, say, `Reweights` objects.)

Anyway…

---

<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: [November 28, 2017, 7:21am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343/11 "2017-11-28T07:21:31Z")

</div>

> [@Sleort](#):
>
> So are there some guidelines on when one should use callable objects f(x) and when one should use the evaluate(f, x) structure?

Generally, for me the choice between `f(x)` and `g(f, x)` would boil down to

1. whether `f` is close to the idea of a mathematical (“pure”) function, (use `f`)
2. whether I want to pass it to another function (eg `map`), (use `f`)
3. whether I want to do something else with `f`, (use `g`),
4. whether `g` is common enough as an operation that it deserves its own function name, (use `g`),
5. whether I have more `f`s or `g`s.

Having _both_ `f(x)` (= `g(f,x)`) and `h(f, x)` are confusing (I think, this may be subjective). Having `h!(f, x)` at the same time just makes it worse, for me this would violate (1) above.

In your case, since you have both modifying and functional calls, I would stick to `g(f, x)` and `g!(f, x)`.

Again, this is largely subjective, YMMV. Sometimes I rewrite interfaces back and forth and go in circles for a while. Hope this helps.

---

<div class="post-metadata">

### Author: ![Sleort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sleort/32/4875_2.png) [@Sleort](https://discourse.julialang.org/u/Sleort)
#### Post date: [November 28, 2017, 7:31am UTC](https://discourse.julialang.org/t/appending-to-names-of-callable-objects-functors-that-modify-their-argument/7343/12 "2017-11-28T07:31:14Z")

</div>

@Tamas_Papp Thanks for your thoughts! Yeah, you and @juliohm have made me drift towards the `g(f, x)` and `g!(f, x)` side (for now… I also tend to “go in circles” 🙂 )
