# 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:** 9

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [October 9, 2022, 12:17am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/168 "2022-10-09T00:17:43Z")

</div>

> [@bertschi](#):
>
> `Unfortunately, -- is invalid syntax`

Yes this is why I picked it: assurance that implementing it in the language wouldn’t cause any breaking changes.

> [@bertschi](#):
>
> For what it’s worth, what about this syntax using `@chain`?

Much too inconvenient. If I had to recite the Lord’s Prayer every time I expressed my thoughts, I’d never express my thoughts.

> [@anon56330260](#):
>
> Maybe a much simple solution is to break the syntax (in Julia 2) and reserve the usage of `->` for OOP function call and use `->>` for anonymous function (or a Haskell style anonymous function like \x → x + y).

Better yet, we could use ↦ (`\mapsto<tab>`) for anonymous function definitions, to be consistent with mathematics (as everyone knows, → is used for specifying a function’s domain and codomain, e.g. 𝑓 : ℝ → ℝ⁺, while ↦ is used for function definitions, e.g. 𝑥 ↦ 𝑥² 😜)

I’m kidding, I’m kidding. Maybe. I appreciate the openness to changing the language. But imo, there would need to be a very compelling reason to break anonymous function syntax. I’d rather break `..` than `->`, but I’m growing partial to using `--` for UFCS method calls since it wouldn’t need any breaking changes, is reasonably easy to type, and can easily be verbalized as “dash.”

Another reminder: UFCS is not an object-oriented concept, so let’s not confuse it with OOP. (I might have to append this reminder to every message. 😆)

> [@aplavin](#):
>
> In Julia, many data processing functions take the “object” they act on as the last argument, not the first. … Moreover, many of these functions take another “lambda” function as an argument.

Yeah, I get the hangup on `map`, `reduce`, `filter`, etc.: functions that describe sentences of the form, “Do something when applying _this behavior_ to _that collection_.” Perhaps they could have as easily followed the form, “Do something when taking _this collection_ and applying _that behavior_ to it,” but that’s not how the language authors decided to do it. [Not true; a function call of the former form is transformed into the latter form when using the `do` statement! 😅]

UFCS syntax isn’t optimal for chaining using these methods, I agree. However,

- _most_ functions don’t follow this form of taking a function as a first argument,
- broadcasting covers most use cases you’d otherwise use `map` for, and
- there are additional benefits to UFCS beyond chaining, such as autocomplete and the simple ability to express thoughts in noun→verb form,

so let’s not throw the babies out with the bathwater.

Further, so long as the object is captured, UFCS can still bring some convenience. Example:

```julia-auto
arr = collect(-2:2)
# cube each element and filter by positives
let cube(x) = x^3, ispositive(x) = x > 0
    arr--(cube--map)()--(ispositive--filter)() == [1, 8] # true
end

```

In English it’d read like: “Take the array, apply a cube mapping, and then apply a positive filtering.” Unfortunately it gets ugly if the anonymous functions aren’t named.

Or since these are now single-argument functions, one could chain with pipes to avoid parentheses:

```julia-auto
arr |> cube--map |> ispositive--filter

```

or compose a function as:

```julia-auto
newfunc = ispositive--filter ∘ cube--map
newfunc(arr)

```

Admittedly it’d be nicer to say “Take the array, map onto it the cubing function, then filter it by positives” but I’m working with what I’ve got until I can find good syntax for sending the object to the last argument.

You would never ever ever want to do this, but for illustration:

```julia-auto
mapreduce(√, +, arr) == (arr |> (+ -- (√ -- mapreduce)))

```

Again though, UFCS is better suited to the greater universe of functions that _don’t_ take a function as a first argument, such as

```julia-auto
"Hello, world!"--split(",")--replace.("o"=>"e")--join(":") == "Helle: werld!" # true
document--root()--firstelement()--setnodecontent!("Hello, world!")

```

There’s a big world of functions out there structured like this.

> [@aplavin](#):
>
> _disclaimer: author of datapipes_

Oh! I am honored. My favorite bit is the syntax of any expression of `_` becoming a single-argument anonymous function. That feels like it should be a core language feature.

> [@aplavin](#):
>
> Does this convenience issue - that can easily be solved in a package - really warrant a syntax change in Julia?

The point of discussion is which features that make common human thought patterns convenient, concise, and easy to express should be in the language, regardless what specific problem is being solved with the code and what packages are loaded for it. Being careful of course to select only the thought patterns which are _so common_ and _so useful_ that it’d be silly not to implement them, especially as we approach a new major version.

Imagine if the “if you want convenience just make a macro and package it” attitude was applied to list comprehensions, matrices, broadcasting, or any of Julia’s best and most frequently used syntax sugar. Imagine all the syntax clashes with other packages!🥴

P.S. Taking inspiration DataPipes.jl and from Clojure’s `->` threading into first argument and `->>` threading into last argument, I’m contemplating `---` to pass the object into the last non-keyword argument. Maybe? 🤔

```julia-auto
arr---map(cube)---filter(ispositive)

```

Then the ugly example from above could be

```julia-auto
mapreduce(√, +, arr) == arr---mapreduce(√, +)

```

`---` could be verbalized as “em-dash,” which appropriately sounds like “end-dash.”

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [October 9, 2022, 1:57am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/169 "2022-10-09T01:57:20Z")

</div>

Hu, now you seem to get carried away a bit … let me just comment on some of your ideas:

> [@uniment](#):
>
> Another reminder: UFCS is not an object-oriented concept, so let’s not confuse it with OOP. (I might have to append this reminder to every message. 😆)

True, but I would say it just hides/fixes an inconsistency in languages which have functions and OOP methods. Languages using either one of them exclusively have much less need for such, e.g., Haskell does not have or need a special syntax for method or even field access – its all just functions – and Smalltalk has no special syntax for function call.  
Imho Smalltalk has one of the best syntax for message-passing OOP though, e.g.,

```Smalltalk
arr at: 1 put: "Hello"; at: 2 put: "there"; yourself.

```

> [@uniment](#):
>
> Further, so long as the object is captured, UFCS can still bring some convenience. Example:
> 
> ```julia
> arr = collect(-2:2)
> # cube each element and filter by positives
> let cube(x) = x^3, ispositive(x) = x > 0
> arr--(cube--map)()--(ispositive--filter)() == [1, 8] # true
> end
> 
> ```
> 
> In English it’d read like: “Take the array, apply a cube mapping, and then apply a positive filtering.” Unfortunately it gets ugly if the anonymous functions aren’t named.
> 
> Or since these are now single-argument functions, one could chain with pipes to avoid parentheses:
> 
> ```julia
> arr |> cube--map |> ispositive--filter
> 
> ```
> 
> or compose a function as:
> 
> ```julia
> newfunc = ispositive--filter ∘ cube--map
> newfunc(arr)
> 
> ```

Now, you seem to overload the syntax in that it does currying, i.e., `fun = cube -- map` is a function, whereas `arr--fun` applies that function to produce a value. In Haskell that is quite convenient, but it is hard to support in languages with variadic functions as the compiler would not know if `map(f, x)` is already complete or you wanted `y -> map(f, x, y)`. It’s a compromise in the end, but you probably can’t have both without something more explicit like `partial` above in Julia (which has a lot of variadic functions).

> [@uniment](#):
>
> Imagine if the “if you want convenience just make a macro and package it” attitude was applied to list comprehensions, matrices, broadcasting, or any of Julia’s best and most frequently used syntax sugar. Imagine all the syntax clashes with other packages!🥴

That is true, but language syntax requires a lot of thought about the proper abstractions/semantics behind it to be widely useful. Just consider how long the development of [LINQ](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/) took, which is basically monad comprehensions, yes, the famous [Monads](https://wiki.haskell.org/Monad) from Haskell that is (I have ranted [elsewhere](https://bertschi.github.io/donot.html) why I don’t like the `do`-notation for monads).

> [@uniment](#):
>
> Much too inconvenient. If I had to recite the Lord’s Prayer every time I expressed my thoughts, I’d never express my thoughts.

Well, to my eyes it appears quite similar to read and type. Yet, if you really want to express your thoughts in a notation it’s important that it supports formal manipulations, i.e., to prove equality between seemingly different implementations or derive novel algorithmic ideas in the first place. I know just about two notations/languages which can and have been used for that purpose, namely [APL](https://dl.acm.org/doi/10.1145/358896.358899) and [Squiggol](https://en.wikipedia.org/wiki/Bird%E2%80%93Meertens_formalism).

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [October 9, 2022, 3:26am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/170 "2022-10-09T03:26:04Z")

</div>

> [@uniment](#):
>
> And that’s where noun→verb chaining with UFCS shines.

I think it’s a problem to make programming languages adopt English grammar.

1. Many major languages diverge from English grammar, and English grammar isn’t so rigid either (passive vs active voices switches the order of subject and object). I know programming languages already use English words, but I don’t think we should make things even harder for non-English speakers.
2. Even if we want to, there is a limit to how much we can make programming languages resemble natural languages. COBOL was intended to be English-like, but it barely bore a passing resemblance to human speech, and other languages since then have quickly converged on less wordy ways to structure programs.
3. Variables aren’t so easily classifiable as subjects vs objects vs verbs. Any type can have callable instances, so functors and nested functions can act as either noun or verb. We have lots of higher-order functions too, where the “verbs” become “nouns”.
4. Having many syntax options to write the same program complicates the language. It may make sense for DSL macros to remove tons of boilerplate in specific libraries, but it’ll just be confusing for newcomers to learn more ways to just do function calls in the core language. You had a similar criticism about Chain.jl and Pipe.jl, and this would just add another (less flexible) syntax to that pile. Replacing piping with one of the enhanced piping libraries seems simpler and more beneficial than incorporating your additional syntax.

> [@uniment](#):
>
> Consider the following instructions describing a sequence of transformations to a fruit:
> 
> > Take an orange. Peel it with your fingernails. Split it. Put it in a bowl. Eat it slice by slice.
> 
> Imagine if the English language insisted I present this sequence as:
> 
> > Eat the (put the (split the (peel an orange with your fingernails)), in a bowl), slice by slice.

I mean, we could just do that in separate lines in order: `peeled_orange = peel(fingernails, orange); slices = split(peeled_orange); put!(bowl, slices); for i in 1:length(bowl) eatfrom!(bowl) end`. Piping just saves us from making temporary variables if we can conceptualize the program as a series of transformations on a special input, which we can’t always do e.g. binary operations.

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [October 9, 2022, 7:04am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/171 "2022-10-09T07:04:17Z")

</div>

> [@bertschi](#):
>
> let me just comment on some of your ideas:

Just one idea, really 😅

> [@bertschi](#):
>
> Now, you seem to overload the syntax in that it does currying, i.e., `fun = cube -- map` is a function, whereas `arr--fun` applies that function to produce a value.

This is a misunderstanding. `arr--fun` is a function, and `arr--fun()` applies the function to produce a value. For illustration purposes, imagine `--` and `---` as binary operators defined as

```julia
--(obj, meth) = (args...; kwargs...) -> meth(obj, args...; kwargs...)
---(obj, meth) = (args...; kwargs...) -> meth(args..., obj; kwargs...)

```

such that `arr--fun` produces a function, `(args...; kwargs...) -> fun(arr, args...; kwargs...)`.

> [@Benny](#):
>
> I think it’s a problem to make programming languages adopt English grammar.

This is a strawman argument.

I’m not proposing to create a JIT compiler for the English language! Just to support noun→verb ordering, which we already do with the `|>` pipe, in a way that’s more powerful (ability to pass other arguments) **and** more convenient (typing the `|>` characters is error-prone). _That. Is. All._

I only offer natural language examples to draw analogies and to demonstrate how common these orderings are. If we really dive into the weeds, UFCS is exactly _not_ supported in English sentences. Languages like English and Chinese are SVO (subject-verb-object) languages, and since the computer is implicitly the subject in all procedural commands, the syntax `mymethod(my_object)` is already exactly in SVO order. Languages like Latin, Hindi and Korean are SOV (subject-object-verb) languages, and the UFCS syntax `my_object--mymethod()` is in this order. UFCS is closer to Sanskrit than to English!

All that to say, it’s remarkable that English speakers can learn object-verb ordering _and came to prefer it in many contexts_ despite it being less natural to us; it’s probable that there’s something special about it.

Anyway, the point is to support common _thought patterns_ regardless of the programmer’s native tongue. And even though English is an SVO language, _mentally_ we do employ object→verb→verb→verb chaining.

Note: despite being a SVO language, thankfully English provides a keyword explicitly for convenient chaining: the word “it,” which allows us to keep the object in memory and continue calling verbs on it without renaming it at each step.

> [@Benny](#):
>
> Having many syntax options to write the same program complicates the language.

Agree, hence why it’s prudent to ensure they’re the most useful ones. What has stood the test of time seems like a decent measure, which UFCS has done, satisfying multiple generations (boomers, gen x, millennials, and zoomers) despite all manner of other fashions rising and falling through those decades.

Is it just a persistent but ultimately doomed ugly fad, like Java? Possible. But considering that the word “it” doesn’t seem to be fading from the English language, I think not.

> [@Benny](#):
>
> Replacing piping with one of the enhanced piping libraries seems simpler and more beneficial than incorporating your additional syntax.

Finally a reasonable statement. I might possibly be persuaded, let’s see. I suspect @aplavin can provide the best arguments (or counter-arguments) here.

> [@Benny](#):
>
> Piping just saves us from making temporary variables if we can conceptualize the program as a series of transformations on a special input

Yes. Or at least, subroutines of the program. Very handy.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [October 9, 2022, 7:20am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/172 "2022-10-09T07:20:14Z")

</div>

> [@uniment](#):
>
> Just to support noun→verb ordering, which we already do with the `|>` pipe, in a way that’s more powerful (ability to pass other arguments) **and** more convenient (typing the `|>` characters is error-prone). _That. Is. All._

That’s exactly what I mean by making programming languages adopt English grammar, maybe I should’ve been more precise. I think your proposal would be clearer and more convincing if you talked about programming/math linguistics, e.g. prefix vs postfix notation, instead of natural languages and all their needless complications. Variables, instances, and functions really just don’t fit well into nouns, subjects, objects, and verbs.

> [@uniment](#):
>
> All that to say, it’s remarkable that English speakers can learn object-verb ordering _and came to prefer it in many contexts_ despite it being less natural to us

Passive voice is pretty natural “this program was written years ago.”

> [@uniment](#):
>
> And even though English is an SVO language, _mentally_ we do employ object→verb→verb→verb chaining.

I think putting an input through a series of input-output systems is more of a math and engineering concept. I definitely can’t think of a language with long serial verb chains.

---

<div class="post-metadata">

**Author:** ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)\
**Post date:** [October 9, 2022, 8:05am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/173 "2022-10-09T08:05:39Z")

</div>

> [@uniment](#):
>
> I’m kidding, I’m kidding. Maybe. I appreciate the openness to changing the language. But imo, there would need to be a very compelling reason to break anonymous function syntax. I’d rather break `..` than `->`, but I’m growing partial to using `--` for UFCS method calls since it wouldn’t need any breaking changes, is reasonably easy to type, and can easily be verbalized as “dash.”

I think `->` is widely used than `..` in any OOP language. It’s important to have consistence with other languages, to attract potential users, given that this will become the mostly used syntax once we add this to the language. In addition, `->` and ‘.’ are thoroughly tested by programmers and become standard for OOP language. So it’s simply impossible for `..` or other unicode notations to be adopted into the language.

Another consideration here is that I believe anonymous functions will be discouraged in the future, due to the growing desire of static compilation. Therefore, library writers will prefer using functor (singleton type which subtypes `Function`). This will make anonymous functions less useful in Julia. Therefore, it’s reasonable to use a more complicated syntax (whatever it’s `->>, |->, \->` ) for them.

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [October 9, 2022, 8:19am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/174 "2022-10-09T08:19:43Z")

</div>

> [@Benny](#):
>
> I think your proposal would be clearer and more convincing if you talked about programming/math linguistics

Fair.

> [@Benny](#):
>
> Passive voice is pretty natural “this program was written years ago.”

Interesting point. I definitely don’t think in a passive voice when chaining function calls, but maybe other people do 😅.

> [@Benny](#):
>
> I definitely can’t think of a language with long serial verb chains.

The example I gave of peeling the orange is one such verb chain. It uses “it” to continue “threading” (to use Clojure language) the orange through successive verb calls.

---

<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:** [October 9, 2022, 8:34am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/175 "2022-10-09T08:34:28Z")

</div>

> [@anon56330260](#):
>
> Another consideration here is that I believe anonymous functions will be discouraged in the future, due to the growing desire of static compilation. Therefore, library writers will prefer using functor (singleton type which subtypes `Function`). This will make anonymous functions less useful in Julia.

Can you elaborate on how you got to that conclusion? Anonymous functions already subtype `Function`:

```julia
julia> anon = x -> 2x
#3 (generic function with 1 method)

julia> typeof(anon)
var"#3#4"

julia> typeof(anon) |> supertype
Function

```

I also don’t see how anonymous functions themselves prevent static compilation - they are just callable structs under the hood, capturing the state required for closures.

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [October 9, 2022, 8:42am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/176 "2022-10-09T08:42:33Z")

</div>

> [@anon56330260](#):
>
> I think `->` is widely used than `..` in any OOP language. It’s important to have consistence with other languages, to attract potential users, given that this will become the mostly used syntax once we add this to the language. In addition, `->` and ‘.’ are thoroughly tested by programmers and become standard for OOP language. So it’s simply impossible for `..` or other unicode notations to be adopted into the language.

I disagree. Julia is not an object-oriented language, and the behavior I’m proposing is _not_ the same as the `->` operator in C/C++, so using `->` here would be a breaking change that at best adds mild visual appeal and at worst just adds confusion.

Also, `->` doesn’t have that meaning in many other OOP languages anyway (in Java and Ruby it’s used for lambda functions; JavaScript has no such operator afaik; in Python it declares the function’s codomain).

Anyway, I’ve already discussed a similar topic here:

> [@uniment](#):
>
> > [@Benny](#):
> >
> > OOP programmers won’t like using anything but `.` for this; `..` is already pushing it and `--` will be a non-starter.
> 
> Not convinced. I prefer `+` for string concatenation and `*` for string replication, but Julia uses `*` and `^` respectively. It’s not the end of the world.

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [October 9, 2022, 9:08am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/177 "2022-10-09T09:08:22Z")

</div>

> [@uniment](#):
>
> > [@bertschi](#):
> >
> > let me just comment on some of your ideas:
> 
> Just one idea, really 😅

Fair enough, should have said arguments.

> [@uniment](#):
>
> > [@bertschi](#):
> >
> > Now, you seem to overload the syntax in that it does currying, i.e., `fun = cube -- map` is a function, whereas `arr--fun` applies that function to produce a value.
> 
> This is a misunderstanding. `arr--fun` is a function, and `arr--fun()` applies the function to produce a value. For illustration purposes, imagine `--` and `---` as binary operators defined as
> 
> ```julia
> --(obj, meth) = (args...; kwargs...) -> meth(obj, args...; kwargs...)
> ---(obj, meth) = (args...; kwargs...) -> meth(args..., obj; kwargs...)
> 
> ```
> 
> such that `arr--fun` produces a function, `(args...; kwargs...) -> fun(arr, args...; kwargs...)`.

Indeed, I had missed that – it was late already 😀.  
But then, your only issue is that `--` and `---` are invalid infix operators, right? Other than that your functions implement the desired functionality, i.e., without the need for macros or even changes in lowering etc.

Let me try to define [infix operators](https://stackoverflow.com/questions/60321301/user-defined-infix-operator) using any of the still available symbols and see how it works out. Looks like `⧺` and `⧻` are not taken yet.  
In a sense, `⧺` would give [reverse Polish notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation) with an explicit spacing and marker when you apply a verb, i.e.

```julia
⧺(obj, meth) = (args...; kwargs...) -> meth(obj, args...; kwargs...)

((3 ⧺ (4 ⧺ (-)))() ⧺ (5 ⧺ (+)))()

```

which does not look nice currently, as the operator would need to associate to the right and bind more strongly than function application, i.e., `3 ⧺ 4 ⧺ (-)() ⧺ 5 ⧺ (+)()`. Thus, even though it’s all functions the Julia parser would still need changes to support the right infix operator.  
But, now I like your idea, i.e., [Forth](https://en.wikipedia.org/wiki/Forth_(programming_language)) I see you! Would still be reluctant to allow user-defined infix operators a la Haskell though.

> [@uniment](#):
>
> I’m not proposing to create a JIT compiler for the English language! Just to support noun→verb ordering, which we already do with the `|>` pipe, in a way that’s more powerful (ability to pass other arguments) **and** more convenient (typing the `|>` characters is error-prone). _That. Is. All._

Especially on a German keyboard, typing `|>` is even worse. I’m not convinced though that `--` and `---` are less error prone, i.e., given that `-` is already widely used it reminds me of the equality confusion in Javascript etc.

---

<div class="post-metadata">

**Author:** ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)\
**Post date:** [October 9, 2022, 9:12am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/178 "2022-10-09T09:12:21Z")

</div>

Why not simply make a vote? This is easier. I think at least I can do this in the Chinese community and let people choose over `->` and `..`. We have a telegram group with thousands of people, therefore we can investigate the popularity of different syntax. So the options will be like:

1. Break syntax of anonymous function and use `->` for dot call
2. Use `..`, `|->` or any other symbols
3. Do nothing and use macro or any other things

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [October 9, 2022, 9:18am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/179 "2022-10-09T09:18:49Z")

</div>

Ok, let me start:

1. No
2. Maybe, but get the associativity right and remember that in the latest proposal `--` was no longer UFCS, but reverse partial application which is much more powerful (and useful?).
3. Yes

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [October 9, 2022, 9:42am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/180 "2022-10-09T09:42:50Z")

</div>

> [@bertschi](#):
>
> Other than that your functions implement the desired functionality, i.e., without the need for macros or even changes in lowering etc. … even though it’s all functions the Julia parser would still need changes to support the right infix operator.

Yes! Now we’re on the same wavelength.

In addition to binding more tightly, changes might be needed to make broadcasting work properly. But yes, it almost works as-is.

> [@bertschi](#):
>
> I’m not convinced though that `--` and `---` are less error prone, i.e., given that `-` is already widely used it reminds me of the equality confusion in Javascript etc.

My claim that `--` and `---` are less error-prone has to do with how easy it is to hit the right keys. I haven’t yet fully thought through the ramifications on readability, but so far I don’t dislike it. Could use some road testing perhaps.

> [@bertschi](#):
>
> remember that in the latest proposal `--` was no longer UFCS, but reverse partial application which is much more powerful (and useful?)

You’re right, calling it “UFCS” was probably a mistake, considering that UFCS still fashions its syntax to mimic property getting. I never realized that what I’ve been describing could be used for Reverse Polish Notation though! 🤯

```julia
3 -- 4 -- -() -- 5 -- +() == 6 # true

```

I’ll never get used to that. All I wanted was `obj--meth1(args1...)--meth2(args2...)` 😆

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [October 9, 2022, 9:45am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/181 "2022-10-09T09:45:39Z")

</div>

> [@anon56330260](#):
>
> Why not simply make a vote? This is easier.

Easier to do, harder to do meaningfully. High probability of degrading the SNR of the discussion to zero.

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [October 9, 2022, 10:31am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/182 "2022-10-09T10:31:08Z")

</div>

> [@uniment](#):
>
> > [@bertschi](#):
> >
> > remember that in the latest proposal `--` was no longer UFCS, but reverse partial application which is much more powerful (and useful?)
> 
> You’re right, calling it “UFCS” was probably a mistake, considering that UFCS still fashions its syntax to mimic property getting. I never realized that what I’ve been describing could be used for Reverse Polish Notation though! 🤯
> 
> ```julia
> 3 -- 4 -- -() -- 5 -- +() == 6 # true
> 
> ```
> 
> I’ll never get used to that. All I wanted was `my_object--mymethod(args...)` 😆

Was just thinking it through 😀  
In the arithmetic example, the result might be somewhat unexpected when associating to the right:

- The above parses as `(5 + (4 - 3))`, i.e., reads from the back as `--` inserts as the first argument.
- Yet, `[1,2,3] -- iseven -- filter() -- sqrt -- map()` would give the intended `map(sqrt, filter(iseven, [1,2,3]))`.

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [October 9, 2022, 10:46am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/183 "2022-10-09T10:46:08Z")

</div>

> [@bertschi](#):
>
> Yet, `[1,2,3] -- iseven -- filter() -- sqrt -- map()` would give the intended `map(sqrt, filter(iseven, [1,2,3]))`.

That’s a very interesting realization. How cool! Right-associativity basically eliminates the need for `---`.

Thanks for helping me think this through, it’s looking even better than I had intended. 😅 Glad to have people smarter than me looking at this!

---

<div class="post-metadata">

**Author:** ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)\
**Post date:** [October 9, 2022, 12:08pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/184 "2022-10-09T12:08:35Z")

</div>

Eventually, you need to let people vote over these things (suppose we indeed want to move towards this direction and we do have several options to choose), because the usage of syntax sugar is to please most users. So a vote can tell us how people prefer different syntax.

Anyway, since some core team developers have already showed their objection to our proposals, whatever it’s `->`, `..` or `--`, I guess it will take a long time for this feature to land in Julia (or maybe never), unless some really influential Julian or companies in Julia community make their needs explicit to core terms. I think if you really really want to make your proposal into Julia, then you should spend some time convincing them instead of me or other people, because they are the one who have rights to make final decisions. My personal preference over syntax may never be changed.

---

<div class="post-metadata">

**Author:** ![albheim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albheim/32/34660_2.png) [@albheim](https://discourse.julialang.org/u/albheim)\
**Post date:** [October 9, 2022, 12:50pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/185 "2022-10-09T12:50:21Z")

</div>

> [@uniment](#):
>
> especially as we approach a new major version.

> **[Why Julia 2.0 Isn’t Coming Anytime Soon (and Why That Is a Good Thing)](https://towardsdatascience.com/why-julia-2-0-isnt-coming-anytime-soon-and-why-that-is-a-good-thing-641ae3d2a177)**
>
> Julia 2.0, why you shouldn’t hold your breath waiting for it.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [October 9, 2022, 1:23pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/186 "2022-10-09T13:23:20Z")

</div>

> [@bertschi](#):
>
> `[1,2,3] -- iseven -- filter() -- sqrt -- map()` would give the intended `map(sqrt, filter(iseven, [1,2,3]))`.

Parentheses are more straightforward when there are 3+ calls in a branching order like `f( g(a, b), h(x, y, z) )`, even if we wrote the callable last like `( (a, b)g, (x, y, z)h )f`.

Reverse Polish notation works without any parentheses sometimes because each operation/method/function only consumes a fixed number of arguments on a stack. So if you treat `+` and `*` as binary operations, `a b + c d + *` is interpreted as `*( +(a,b), +(c,d) )`, rather than `*(+( +(a,b), c, d ))`. Unfortunately/fortunately, multimethods or overloaded functions can have call signatures with different number of arguments, so parentheses become crucial. For example, your notation could’ve been interpreted instead as `map(sqrt, filter(iseven), [1,2,3])`.

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [October 9, 2022, 4:16pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/187 "2022-10-09T16:16:53Z")

</div>

> [@Benny](#):
>
> Reverse Polish notation works without any parentheses sometimes because each operation/method/function only consumes a fixed number of arguments on a stack. So if you treat `+` and `*` as binary operations, `a b + c d + *` is interpreted as `*( +(a,b), +(c,d) )`, rather than `*(+( +(a,b), c, d ))`. Unfortunately/fortunately, multimethods or overloaded functions can have call signatures with different number of arguments, so parentheses become crucial. For example, your notation could’ve been interpreted instead as `map(sqrt, filter(iseven), [1,2,3])`.

In general, that is correct. The cool thing about this notation though is that `()` explicitly marks an application, i.e., `--` simply puts its arguments onto the stack and never applies a function. Everything on the stack is then consumed by the function on top of the stack on `()`. Thus, `[1,2,3] -- iseven -- filter () -- sqrt -- map ()` is unambiguously interpreted as `map(sqrt, filter(iseven, [1,2,3]))`.  
On the other hand, it means that the interpretation `*( +(a , b), +(c, d))` needs additional parenthesis, i.e., `a -- b -- + () (c -- d -- + ()) -- * ()`. Seems that every notation has its preferred uses, but the one proposed here seems quite nice for processing pipelines were a single argument is successively transformed on each `()`, i.e., as in the `map`, `filter` chain. Maybe not surprising as this use was the original motivation, i.e., `obj -- transform_1 -- transform_2` etc.

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

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