# Allowing the object.method(args...) syntax as an alias for method(object, args ...)

**URL:** https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051
**Category:** Internals & Design
**Tags:** question, design
**Created:** [May 29, 2021, 5:09pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051 "2021-05-29T17:09:54Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![gianmariomanca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gianmariomanca/32/25597_2.png) [@gianmariomanca](https://discourse.julialang.org/u/gianmariomanca)
#### Post date: [May 29, 2021, 5:09pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/1 "2021-05-29T17:09:54Z")

</div>

I started exploring Julia very recently and I like it. I’ve been chatting about it with colleagues.

Many people coming from OOP languages (Python…) like the syntax object.method(a,b,c…).  
Since you can get a preview of the available methods acting on object with tab press.  
Would it be possible to have that in Julia (I’m assuming it’s not already there) to improve usability?

Let say I define a IIR filter struct

```julia
mutable struct IIRfilter
	state;
	alpha;
	IIRfilter(state,alpha) = 0<=alpha<=1 ? new(state,alpha) : error("alpha must between 0 and 1")
	IIRfilter(alpha) = 0<=alpha<=1 ? new(NaN,alpha) : error("alpha must be between 0 and 1")
end

```

and a method

```julia
function filter(filter::IIRfilter, x)
	if isnan(filter.state)
		filter.state = x
	else
		filter.state = filter.alpha*filter.state + (1-filter.alpha)*x;
	end
	return filter.state 
end

```

I can now use my filter

```julia
begin
	N = 3000
	f = IIRfilter(0.9)
	Random.seed!(1)
	xv = randn(N,1);
	xf = zeros(N,1);
end;

```

```julia
begin
	for i = collect(1:N)
		xf[i] = filter(f,xv[i])
	end
end

```

It would be nice to be able to start typing

`f.`

the press a tab and get

```julia
f.state
f.alpha
f.filter(...)

```

as options instead of just

```julia
f.state
f.alpha

```

basically get a preview of all available methods for the IIRfilter type (where IIRfilter is the first argument of the method if we are thinking about standard OOP, or maybe a more general solution that is closer in spirit with multiple dispatch?)

Is there a reason why we might not want this or we would actually want to actively discourage it?

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [May 29, 2021, 5:40pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/2 "2021-05-29T17:40:18Z")

</div>

This is very unlikely to ever be supported in julia anytime soon. What’s more likely, is for text editors to come up with better ways to help you do autocompletion.

---

<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: [May 29, 2021, 5:51pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/3 "2021-05-29T17:51:59Z")

</div>

It’s definitely possible to do this already, see Jeff’s old answer here:

[https://stackoverflow.com/a/39150509/3263164](https://stackoverflow.com/a/39150509/3263164)

Whether this is a good idea is another question since multiple dispatch is strictly more powerful than single dispatch in the form of class-based OOP and designing interfaces like that is generally considered quite unidiomatic in Julia. There are other proposals to solve the tab-completion problem you mentioned, see for example [https://github.com/JuliaLang/julia/pull/38791](https://github.com/JuliaLang/julia/pull/38791).

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [May 29, 2021, 6:28pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/4 "2021-05-29T18:28:19Z")

</div>

Another reason this is odd is because in Julia, the first argument is already “special” because you can construct anonymous functions using the `do` syntax that get placed into the first argument, i.e. `filter(t -> t > 1, [1, 2, 3])`. Adding this kind of syntax would make the first argument “special” in a different, somewhat contradictory way.

---

<div class="post-metadata">

### Author: ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)
#### Post date: [May 29, 2021, 7:19pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/5 "2021-05-29T19:19:50Z")

</div>

> [@simeonschaub](#):
>
> There are other proposals to solve the tab-completion problem you mentioned, see for example [?(x, y)TAB completes methods accepting x, y by timholy · Pull Request #38791 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/38791).

It would be great if this could make it into Julia 1.7.

---

<div class="post-metadata">

### Author: ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)
#### Post date: [May 29, 2021, 9:00pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/6 "2021-05-29T21:00:09Z")

</div>

This is

> **[Uniform Function Call Syntax](https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax)**
>
> Uniform Function Call Syntax (UFCS) or Uniform Calling Syntax (UCS) or sometimes Universal Function Call Syntax is a programming language feature in D and Nim that allows any function to be called using the syntax for method calls (as in object-oriented programming), by using the receiver as the first parameter, and the given arguments as the remaining parameters. UFCS is particularly useful when function calls are chained (behaving similar to pipes, or the various dedicated operators avail Propo...

```julia
d |> x->f(x,y,z) |> x-> g(x,m,n)

```

is easier to write as

```julia
d.f(y,z).g(m,n)

```

The `do` block

```julia
d.f(y,z) do r
    r + 5
end

```

goes to

```julia
f(d, r->r+5, y, z)

```

---

<div class="post-metadata">

### Author: ![gianmariomanca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gianmariomanca/32/25597_2.png) [@gianmariomanca](https://discourse.julialang.org/u/gianmariomanca)
#### Post date: [May 30, 2021, 12:32am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/7 "2021-05-30T00:32:26Z")

</div>

@Mason It’s not just auto-completion in a generic abstract way. And we are talking about the REPL and Jupyter and Pluto. It’s about gaining traction and lowering the entry barrier. I’m talking about a true scenario where a colleague of mine started a new project in Python even though he is an estimator of Julia because not many of his collaborator know Julia and he was too worried about **their** learning curve. The goal it to make people comfortable making the transition because they know they can easily get Python/C++ users on board. If you do that you have very little to lose and a lot to gain I believe.

@jzr thank you for posting the wikipedia article. It was very interesting seeing that there is already a “name” for the topic and seeing the proposals attached in the references of that article.

@simeonschaub , “fancy” solutions are interesting and a few people would get excited by the learning opportunity but in the context I’m referring to it will not help, it might actually have the opposite effect.

---

<div class="post-metadata">

### Author: ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)
#### Post date: [May 30, 2021, 12:39am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/8 "2021-05-30T00:39:05Z")

</div>

Imho this is too big a change if it only lowered the barrier to entry, but it may actually be better for experienced Julians.

–

> [@gianmariomanca](#):
>
> an estimator of Julia

I think “estimatore” goes to “admirer”

---

<div class="post-metadata">

### Author: ![gianmariomanca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gianmariomanca/32/25597_2.png) [@gianmariomanca](https://discourse.julialang.org/u/gianmariomanca)
#### Post date: [May 30, 2021, 12:46am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/9 "2021-05-30T00:46:14Z")

</div>

@jrz, you are right, “admirer”, writing too fast and in an uncomfortable situation, and probably using too many “estimators” 😃

Yes barrier to entry is just one aspect of it, I believe it would have an intrinsic value for the current community. But I would not underestimate the “power” that a low barrier to entry can give to “admirers” within organizations.

---

<div class="post-metadata">

### Author: ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)
#### Post date: [May 30, 2021, 12:48am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/10 "2021-05-30T00:48:15Z")

</div>

> [@simeonschaub](#):
>
> Whether this is a good idea is another question since multiple dispatch is strictly more powerful than single dispatch in the form of class-based OOP and designing interfaces like that is generally considered quite unidiomatic in Julia.

In the SO post, the person object has a fixed set of methods on it that work in the postfix position. In UFCS, all methodswith(Person) can go in the postfix position, so it’s compatible with Julian dispatch, not less powerful. `x.add(y)` is just `add(x,y)`.

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [May 30, 2021, 12:57am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/11 "2021-05-30T00:57:29Z")

</div>

Before continuing @gianmariomanca, I should welcome you to the Discourse community, I’m sorry for forgetting earlier! It’s always nice to see new faces come by.

I get why people want this. You’re not the first person to ask for this, and I’m sure you won’t be the last. This has really been discussed to death in a lot of different places, usually asked for by newcomers, so please understand that if it feels like people aren’t giving your suggestion the proper amount of consideration, it’s because it has been discussed a lot before and the language developers are pretty firmly against it.

I’m not a core developer or someone who has much of a say in the matter at all, but for my part, I think that adding new syntactic forms just to make people coming from class based languages like Python and C++ is a bad idea. That extra bit of familiarity is not going to be of much help, and may actually hurt them because a very common pattern is for people to not realize just got _different_ julia is. It’s it’s own language that has it’s own paradigms, styles, quirks, strengths and weaknesses.

Many people try and write ‘python in julia’ and get confused and upset when it doesn’t do what they expect or doesn’t perform as well as they want.

Uniform function call syntax (the `x.method(y)` syntax) has some nice advantages, but I think once you get used to julia it won’t be missed too often, and ther are real advantages to not using it as well. It’s particularly important to emphasize how Julia is _not_ a single dispatch language, and the first argument to a function is not special.

One point I’ll bring up is that Bjarne Stroustrup, the creator of C++ recently wrote a paper where he called this syntax a mistake, and advocates for a setup in C++ that’s much more like julia.

> Unified function call: The notational distinction between x.f(y) and f(x,y) comes from the flawed OO notion that there always is a single most important object for an operation. I made a mistake adopting that. It was a shallow understanding at the time (but extremely fashionable). Even then, I pointed to sqrt(2) and x+y as examples of problems caused by that view. With generic programming, the x.f(y) vs. f(x,y) distinction becomes a library design and usage issue (an inflexibility). With concepts, such problems get formalized. Again, the issues and solutions go back decades. Allowing virtual arguments for f(x,y,z) gives us multimethods.

Here’s the paper if you want to read more: [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1962r0.pdf](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1962r0.pdf)

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [May 30, 2021, 1:31am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/12 "2021-05-30T01:31:39Z")

</div>

Chain.jl makes this very easy,

```julia
@chain d begin 
    f(x, y, z)
    g(x, m, n)
end

```

Creating syntactic sugar for this kind of pattern is easy. The auto-completion is the hard part, and it seems like there are some serious efforts underway to make it easier.

---

<div class="post-metadata">

### Author: ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)
#### Post date: [May 30, 2021, 2:11am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/13 "2021-05-30T02:11:18Z")

</div>

```julia
julia> length("d.f(y,z).g(m,n)")
15

julia> length("@chain d begin 
           f(x, y, z)
           g(x, m, n)
       end")
49

```

Though most of that cost is fixed.

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [May 30, 2021, 2:15am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/14 "2021-05-30T02:15:22Z")

</div>

`@chain` inserts the last argument into the first of the next call. So you are counting extra arguments. Here is a better comparison

```julia
julia> length("d.f(y,z).g(m,n)")
15

julia> length("@chain d f(y,z) g(m,n)")
22

```

---

<div class="post-metadata">

### Author: ![gianmariomanca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gianmariomanca/32/25597_2.png) [@gianmariomanca](https://discourse.julialang.org/u/gianmariomanca)
#### Post date: [May 30, 2021, 2:50am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/16 "2021-05-30T02:50:11Z")

</div>

@Mason , thank you for welcoming me. I think it was a mistake on my part to bring up “barrier of entry”, it seems to monopolize the attention and bring the discussion in the unproductive direction of “this language vs that language”. I did it just because that episode with my colleague attracted my attention and seemed like a missed opportunity.

In general my attitude in this comment was just “steal” as many good features as possible (which seems very much in line with the spirit behind Julia’s creation when the co-creators wanted it “all”.)

I think you might be misreading Bjarne Stroustrup comment. Yes I agree that is a bad idea to **always** assume that there is one “most-important” argument, but here we are talking about having more options, not less. Nobody wants to remove the standard notation, just adding a new equivalent one with some known advantages, in some of the cases. It’s up to people then to use the best one in each case.

If you ask me doesn’t even have to be only the first argument, if better or more flexible you can make it that you can use the object.method notation when the object is in _any_ position.  
Let’s say you have object f of type IIRfilter and 2 methods m1(IIRfilter,x) and m2(y,IIRfilter) then you can say f.m1(x) and it will call m1(IIRfilter,x) and f.m2(y) and it will call m2(y,IIRfilter). Maybe allow this notation only for methods with no ambiguity, i.e. only one entry of that specific type, since this notation is targeting the “one most important object” case. Just added this comment for the sake of conversation.

In general would the way I wrote the IIRfilter example considered good “Julian”? How would you rewrite it? Wouldn’t x\_f = f.filter(x) look nicer in this case?

---

<div class="post-metadata">

### Author: ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)
#### Post date: [May 30, 2021, 3:09am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/17 "2021-05-30T03:09:06Z")

</div>

I’m not so sure how you want to use this thing, but one useful pattern to know is that you can make the struct callable, so that `x_f = f.filter(x)` just becomes `f(x)`:

```julia
julia> (filter::IIRfilter)(x) =
           if isnan(filter.state)
               filter.state = x
           else
               filter.state = filter.alpha*filter.state + (1-filter.alpha)*x;
           end;

julia> f = IIRfilter(0.9);

julia> f.state
NaN

julia> f(0.5)
0.5

julia> f.(1:3)
3-element Vector{Float64}:
 0.55
 0.6950000000000001
 0.9255

julia> f.state
0.9255

```

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [May 30, 2021, 3:25am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/18 "2021-05-30T03:25:50Z")

</div>

As much as the syntax would be really nice, “obj.somename” already means `getproperty(obj, somename)`

What happens if there is a property and a function with the same name?

Methods are not in the objects namespace (unless you use the JavaClass hack linked above), so this would happen all the time, with confusing results.

---

<div class="post-metadata">

### Author: ![gianmariomanca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gianmariomanca/32/25597_2.png) [@gianmariomanca](https://discourse.julialang.org/u/gianmariomanca)
#### Post date: [May 30, 2021, 4:50am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/19 "2021-05-30T04:50:35Z")

</div>

@mcabbott , thank you. Very interesting pattern when there is only one method. Happy to have learned something new. I’m already impressed by how responsive the community is.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [May 30, 2021, 5:10am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/20 "2021-05-30T05:10:53Z")

</div>

> [@gianmariomanca](#):
>
> Very interesting pattern when there is only one method.

The power of multiple dispatch allows for any number of methods to be added this way:

```julia
julia> mutable struct IIRFilter 
         state::Float64         
         alpha::Float64         
       end                      

julia> (filter::IIRFilter)(state, alpha) = begin                          
          filter.state = state                                            
          filter.alpha = alpha                                            
       end                                                                
                                                                          
julia> (filter::IIRFilter)(x::Float64) = if isnan(filter.state)           
           filter.state = x                                               
       else                                                               
           filter.state = filter.alpha*filter.state + (1-filter.alpha)*x  
       end                                                                
                                                                          
julia> (filter::IIRFilter)(x::Int64) = begin                              
           filter.state = filter.alpha*filter.state + (1-filter.alpha)*x  
       end               
                                                              
julia> f = IIRFilter(0.5, 0.7)                                            
IIRFilter(0.5, 0.7)                                                                                            
                                                                          
julia> f(1)                                                               
0.65                                                                      
                                                                          
julia> f                                                                  
IIRFilter(0.65, 0.7)                                                      
                                                                          
julia> f(1)                                                               
0.755                                                                     
                                                                          
julia> f                                                                  
IIRFilter(0.755, 0.7)                                                     
                                                                          
julia> f(0.01)                                                            
0.5315                                                                    
                                                                          
julia> f                                                                  
IIRFilter(0.5315, 0.7)                                                    
                                                                          
julia> f(NaN, 0.3)                                                        
0.3                                                                       
                                                                          
julia> f                                                                  
IIRFilter(NaN, 0.3)                                                       

```

The problem of course is that you lose some sense of what each combination of arguments actually does. Moreover, you can’t distinguish between two methods with the same number of arguments and the same types of arguments but different behaviour this way.

In julia, there’s a convention that functions that modify one of their arguments are ended with an exclamation mark `!`. So I’d write the above like this:

```julia
mutable struct IIRFilter
    state::Float64
    alpha::Float64
end

# with the (filter::IIRFilter)(...) syntax, this can't be distinguished from the modifying `updateFilter!`
function queryFilter(filter::IIRFilter, query)
    filter.alpha*filter.state + (1-filter.alpha, query)
end

function updateFilter!(filter::IIRFilter, nstate)
    filter.state = if isnan(filter.state)
        nstate
    else
        filter.alpha*filter.state + (1-filter.alpha)*x
    end
end

function updateFilter!(filter::IIRFilter, nstate, nalpha)
    filter.state = nstate
    filter.alpha = nalpha
end

```

So from a usability point of view, I personally prefer to be explicit about modification, and I can’t do that with `(f::IIRFilter)(...)`. You have to either guess, or look it up for a specific combination of arguments.

---

<div class="post-metadata">

### Author: ![gianmariomanca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gianmariomanca/32/25597_2.png) [@gianmariomanca](https://discourse.julialang.org/u/gianmariomanca)
#### Post date: [May 30, 2021, 5:17am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/21 "2021-05-30T05:17:06Z")

</div>

@Raf can you write an explicit example of the ambiguity?

Wouldn’t you get  
f.p for the property and f.p() for the method? or something along those lines? Is it something related to the property itself being a function, or the issue is even more basic in Julia?

This didn’t seem to worry Bjarne Stroustrup too much for the same proposal for C++

> **[n4174.pdf](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4174.pdf)**
>
> 195.72 KB

“The basic suggestion is to define x.f(y) and f(x,y) to be equivalent”

(this is one of the references from [Uniform Function Call Syntax - Wikipedia](https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax) suggested by @jzr )

[Next page](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051.md?page=2)
