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

<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:** [October 7, 2022, 1:29am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/148 "2022-10-07T01:29:59Z")

</div>

Actually its [IntervalSets.jl](https://github.com/JuliaMath/IntervalSets.jl) (I always get this mixed up too)

And also more popular:  
[https://juliahub.com/ui/Packages/IntervalSets/2FHuv/0.7.3?page=2](https://juliahub.com/ui/Packages/IntervalSets/2FHuv/0.7.3?page=2)

@uniment that’s 5% of the ecosystem. Hopefully you can see the difference between pragmatic solutions that are not perfect but can be implemented and merged, and nice ideas that can’t happen in reality.

Also, mandatory:

> [@PSA: Julia is not at that stage of development anymore](https://discourse.julialang.org/t/psa-julia-is-not-at-that-stage-of-development-anymore/44872):
>
> You heard about this brand new exciting programming language called Julia and have some suggestions for how it should work. Wonderful! We’re happy to have you here and help you learn the language and listen to your ideas! However, please be aware that “new” is a relative term. Yes, Julia is newer than, say, C, which was first created in 1972 and standardized in 1989. It is not, however, new in the sense that it is still being freely designed and changed in arbitrary ways. Julia development start…

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [October 7, 2022, 2:06am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/149 "2022-10-07T02:06:47Z")

</div>

[What CBOO means](https://youtu.be/kc9HwsxE1OY?t=1240).

`CBOOCall.jl` has particular characteristics. For example you have to sort of “register” any method you want to include via `@cbooify`. If you are the author of the type then this seems pretty clear; I mean it’s a good idea to make clear which are “instance methods” anyway. If you are not the author, you can still `@cbooify` methods. But this seems less robust, especially if CBOOCall were used widely (it’s not.)

An example of why this might be convenient:

```julia
circ = QuantumCircuit(3)
circ.x(0) # apply an X gate at position 0

```

Adding a gate this way, and the name, is very standard in quantum computing (mostly in Python). In Julia world, everyone says, it’s not a problem it’s just a preference, you’ll get used to it, etc… So you do

```julia
using QuantumCircuits: x
x(circ, 0) # or circ(x, 0) or whatever

```

But, importing a lot of functions with identifiers like `x` could cause headaches. So you could name the function `xgate` or something instead. Or qualify it: `QuantumCircuits.x`. But, these are less convenient. And these gates are used a lot. Obviously, similar examples will arise in other domains. If you give up this method of calling, you are giving up something concrete; it’s not just a matter of taste; red or blue.

There could be other ways to solve this particular problem of wanting many functions with very short names. I don’t recall finding any other contenders, but I may have forgotten.

---

<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 7, 2022, 2:21am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/150 "2022-10-07T02:21:18Z")

</div>

> [@Benny](#):
>
> Why on earth is this thread still going on about major version-breaking `..` changes or piping that is restricted to single-argument functions when CBOOCall.jl was already suggested in that comment? I don’t like making function names properties of a type in a non-OOP language (which is also why I consider this worse than simply inputting the first argument unusually like do-blocks), but if you’re going to do it, that looks like the way to do it. Only thing I don’t like about that package is that I still can’t tell what CBOO stands for.

Because:

- The intent is _ **not** _ to treat functions as _properties_ of types. This isn’t an OO language!
- What is desired is _ **not** _ piping restricted to single-argument functions. We already have that and it sucks.
- What is being discussed is a language feature to support common thought patterns, _ **not** _ a dozen different libraries and macros that solve the problem in different ways and that will never become a standard.

CBOOCall is hoping to solve a very specific problem: allowing functions or objects with very short names (e.g. `x`, `y`, and `z`) to be conveniently accessed from a module without polluting the global namespace. It’s spiffy, but not what we’re discussing. At least not what I’ve been.

But if we _were_ trying to address that, @jlapeyre could’ve just used Julia’s `let` statement. Using CBOOCall’s example:

```julia
using QCircuit # don't export x, y, and z
let x=QCircuit.x, y=QCircuit.y, z=QCircuit.z
    add!(circ, x, 1)
end

```

This could be more convenient if Julia had some methods for object destructuring… or maybe for broadcasting access of properties, for example

```julia
..(obj, props::Tuple{Vararg{Symbol}}) = getproperty.(Ref(obj), props)
using QCircuit
let (x, y, z) = QCircuit..(:x, :y, :z)
    add!(circ, x, 1)
end

```

Or even, maybe Julia could do something in the same spirit as JavaScript’s `with` statement, to create a block where that namespace applies and outside which it doesn’t… perhaps

```julia
with QCircuit
    add!(circ, x, 1)
end

```

Then any objects and methods of the QCircuit module would be available, but only within that block. I’ve seen some gnarly Julia code where this feature would substantially reduce code complexity and interdependence.

… Anyway, I digress.

> [@Elrod](#):
>
> [Intervals.jl](https://invenia.github.io/Intervals.jl/latest/) is [fairly popular](https://juliahub.com/ui/Packages/Intervals/ihXRn/1.8.0?page=2).

> [@Raf](#):
>
> Actually its [IntervalSets.jl](https://github.com/JuliaMath/IntervalSets.jl) (I always get this mixed up too)

Ah. Unfortunate.

> [@Mason](#):
>
> Nobody is going to break compatability just to make people used to class based OO happy. It’s just not going to happen.

Very well.

I guess `--` isn’t being used for anything. Maybe?

```julia
my_object--mymethod()

```

has a ring to it 🤔

Some other possibilities: `**`, `||`,

(Although I’d prefer `||` to be reserved for an operator with same precedence as addition, but sacrifices must be made)

> [@Raf](#):
>
> Also, mandatory:

> [@PSA: Julia is not at that stage of development anymore](https://discourse.julialang.org/t/psa-julia-is-not-at-that-stage-of-development-anymore/44872/1):
>
> Along with the 1.0 release came a promise: we will not break your working Julia code until Julia 2.0.

We’re already on 1.8… _queue meme of scheming raccoon_

---

<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 7, 2022, 2:29am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/151 "2022-10-07T02:29:15Z")

</div>

1)Conventions set by OOP languages and 2) easily colliding names that shouldn’t be encapsulated and exported by the module seem like reasonable justifications. For completion’s sake, I would only ask why `circ(:x, 0)` doing `getproperty(QuantumCircuits, :x)(circ, 0)` isn’t enough. My guess is that it’s type-unstable, but I think the compiler does extra tricks with `getproperty` so I’m not sure.

---

<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 7, 2022, 2:44am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/152 "2022-10-07T02:44:07Z")

</div>

> [@uniment](#):
>
> The intent is _ **not** _ to treat functions as _properties_ of types. This isn’t an OO language!

Then you already lost me at using UFCS to mimic OOP syntax.

1. In some OOP languages, you can access encapsulated functions `a = x.f` and call it later `a(y)`. Without the properties approach of CBOOCall.jl, `x.f` wouldn’t even have a valid meaning, and the parser would probably lower that to a `getproperty` call doomed to fail.

2. Concerning autocompletion based on the first type alone, it would only be performant with type properties/class encapsulation. Searching every method ever to find the ones with the right first argument, _especially_ when there are supertypes to check, is excessive work. CBOOCall.jl’s use of `propertynames` would be autocomplete’s best friend.

3. OOP programmers won’t like using anything but `.` for this; `..` is already pushing it and `--` will be a non-starter. R is still getting complaints for using `<-` and `->` as assignment.

4. And the best for last, how would the parser tell if `x.f(y)` should be lowered to `f(x, y)` or if `x` really does have a callable field `f` accepting 1 argument? In fact, those can exist simultaneously:

```julia
struct X f::Function end
x = X(z -> 1)
f(x::X, y) = 2
println(x.f(0), ", ", f(x, 0))

```

> [@uniment](#):
>
> What is desired is _ **not** _ piping restricted to single-argument functions. We already have that and it sucks.

There is Chain.jl and Pipe.jl, they handle piping to any functions iirc.

> [@uniment](#):
>
> ```julia
> using QCircuit # don't export x, y, and z
> let x=QCircuit.x, y=QCircuit.y, z=QCircuit.z
> 
> ```

I wouldn’t write all that, I’d sooner `import QCircuit as QC` and write `QC.x` everywhere.

---

<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 7, 2022, 4:53am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/153 "2022-10-07T04:53:35Z")

</div>

> [@Benny](#):
>
> Then you already lost me at using UFCS to mimic OOP syntax.

The main benefits to UFCS, IMO, have nothing to do with the object oriented paradigm. It’s just nice syntax that allows for noun→verb ordering, without being as limited as the pipe `|>`. Equating UFCS with OOP is a mistake imo. See this post:

> [@Allowing the object.method(args...) syntax as an alias for method(object, args ...)](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/118):
>
> @Mason, It’s particularly important to emphasize how Julia is not a single dispatch language, and the first argument to a function is not special. The do statement would say otherwise, but apparently we limit first-argument “specialness” to anonymous functions only. stuck_out_tongue_winking_eyethinkingpensive@gianmariomanca, 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 her…

> [@Benny](#):
>
> In some OOP languages, you can access encapsulated functions `a = x.f` and call it later `a(y)`.

I’m not convinced that’s necessary. Encapsulation isn’t needed frequently, and an anonymous function can be explicitly defined when it is.

Use of `.` should be limited to property getting. Keep it simple.

> [@Benny](#):
>
> Concerning autocompletion based on the first type alone, it would only be performant with type properties/class encapsulation.

Macbooks are pretty powerful these days… I guess we’ll see. Likely more performant than my brain anyway.

> [@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.

But also, it’s a beneficial reminder to OOP programmers that _this isn’t an OOP concept_; we are calling a _globally accessible method_ with the object as the first argument, \*not\* calling a method _that “belongs” to the object_. Hence why syntax other than `.` is good, to disambiguate for the compiler and also for the person between property getting and method calling.

But please, characters that are easy to type without errors. `|>` is such an error-prone sequence of characters.

> [@Benny](#):
>
> And the best for last, how would the parser tell if `x.f(y)` should be lowered to `f(x, y)` or if `x` really does have a callable field `f` accepting 1 argument?

That’s why I was proposing `..` to disambiguate from property getting. Or perhaps `--`.

> [@Benny](#):
>
> There is Chain.jl and Pipe.jl, they handle piping to any functions iirc.

Yes, there are about half a dozen packages that solve the same problem in slightly different ways, so we’re unlikely to have a standard anytime soon unless it’s incorporated into the language.

> [@Benny](#):
>
> I wouldn’t write all that, I’d sooner `import QCircuit as QC` and write `QC.x` everywhere.

Oh. Oh my. Oh my oh my. I just learned about Julia’s new destructuring syntax. 👏 👏 👏

```julia
(; prop1, prop2, prop3) = my_object # prop1 == my_object.prop1, etc.

```

Game. Changer. Sí se puede.

Strangely it doesn’t seem to work for destructuring modules… that seems like a bug (considering that [my destructuring code above](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/150) _does_ work on modules, and supposedly they work on [the same methods](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236)).

If it worked, @jlapeyre could write:

```julia
let (; x, y, z) = QCircuit
    add!(circ, x, 1)
end

```

Wonderful syntax 🤌

---

<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 7, 2022, 6:07am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/154 "2022-10-07T06:07:42Z")

</div>

Your proposal is logically consistent as it knowingly eschews OOP, so pardon my misunderstanding because this thread was initially about implementing such syntax for OOP users 🫠, who seem to be the vast majority of people requesting this syntax.

At least do-blocks let you input an anonymous function into the conventionally first argument of higher order functions without needing to assign the anonymous function to a variable or the anonymous function splitting the higher order function call in two. By comparison, there is no benefit to having a special syntax for `x--f(y)` but not `y--f(x)` to mean `f(x,y)`; in fact we have Chain.jl and Pipe.jl that can differentiate and do both.

> [@uniment](#):
>
> But also, it’s a beneficial reminder to OOP programmers that _this isn’t an OOP concept_; we are calling a _globally accessible method_ with the object as the first argument, _not_ calling a method _that “belongs” to the object_.

What better reminder of `f` being a global function that does not belong to `x` than writing `f(x, y)`?

---

<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 7, 2022, 8:53am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/155 "2022-10-07T08:53:26Z")

</div>

> [@Benny](#):
>
> By comparison, there is no benefit to having a special syntax for `x--f(y)` but not `y--f(x)` to mean `f(x,y)`; in fact we have Chain.jl and Pipe.jl that can differentiate and do both.

Actually, `x--f(y)` meaning `f(x, y)` brings the benefit of encouraging what is frequently the most reasonable argument ordering, just as it’s reasonable for the subject of a sentence to precede the verb and predicate. At least that’s the case in the spoken languages I know.

Chain.jl, Pipe.jl, etc. offer flexibility over which argument the object gets placed into, rather than forcing it into the first argument. So you get the flexibility to put the predicate before the verb and subject; you can also put an adjective first, or an adverb first. But in exchange for this extra flexibility comes extra awkwardness from having to type more characters and having to _think_ about which argument to place the object in every time. It’s a trade-off which frankly isn’t worth it most of the time, especially if argument orderings are defined well.

> [@Benny](#):
>
> What better reminder of `f` being a global function that does not belong to `x` than writing `f(x, y)`?

Well I would hope the purpose of the language isn’t just to remind me that functions don’t belong to objects! 😅

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.

It’s in an ordering that hardly makes sense, all because we wanted a reminder that verbs don’t belong to nouns. A bit masochistic if you ask me!

And that’s where noun→verb chaining with UFCS shines. It’s piping, but with predicates, adjectives and adverbs.

> [@uniment](#):
>
> Encapsulation isn’t needed frequently, and an anonymous function can be explicitly defined when it is.

I take this back. It’d be easy enough for `my_object--mymethod` to capture `my_object` in an anonymous function:

```julia
my_object--mymethod # yields an anonymous function,
(args...; kwargs...) -> mymethod(my_object, args...; kwargs...)

```

> [@uniment](#):
>
> Strangely it doesn’t seem to work for destructuring modules… that seems like a bug (considering that [my destructuring code above](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/150) _does_ work on modules, and supposedly they work on [the same methods](https://discourse.julialang.org/t/destructuring-syntax-in-julia-1-7/68236)).

Okay so I tried it again, and destructuring actually does work on modules. Not sure what went wrong the first try.

So with that said, @jlapeyre give this approach a shot and see how you like it:

```julia
using QCircuits
let (; x, y, z) = QCircuit
    add!(circ, x, 1)
end

```

---

<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 7, 2022, 7:58pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/156 "2022-10-07T19:58:08Z")

</div>

What about the following translation for your orange example?

```julia
let it = orange
    it = peel(it, fingertips)
    it = split(it)
    it = put(it, bowl)
    eat(it, slice_by_slice)
end

```

Given that I actually like the [`doto` macro](https://clojuredocs.org/clojure.core/doto) from Clojure – making Java interop quite nice despite Clojure strongly favouring functional programming:

```nohighlight
(doto orange
   (peel :fingernails)
   (split)
   (put :bowl)
   (eat :slice-by-slice)) ;; only works by side-effect - doto returns final obj itself

```

Should be rather easy to replicate with a macro in Julia…

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [October 7, 2022, 8:03pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/157 "2022-10-07T20:03:21Z")

</div>

That looks like Chain.jl’s `@chain`.

```nohighlight
@chain orange begin
peel(:fingernails)
split()
put(:bowl)
eat(:slice_by_slice)
end

```

---

<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 7, 2022, 8:58pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/158 "2022-10-07T20:58:43Z")

</div>

Except that `doto` works purely by side-effecting the object and does not pass the results along, i.e.,

```julia
begin
    it = orange
    peel(it, :fingernails)
    split(it)
    put(it, :bowl)
    it # returns the updated object at the end
end

```

Clojure also has chaining macros `->` and `->>` which pass the results of each function as the first and last argument respectively. `doto` is mostly useful for Java objects with side-effecting methods predating fluent interfaces, e.g., not returning the object itself.

---

<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 8, 2022, 1:08am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/159 "2022-10-08T01:08:30Z")

</div>

> [@bertschi](#):
>
> What about the following translation for your orange example?

I’d much prefer

```julia
orange--peel!(:fingertips)--split!()--put!(:bowl)--eat!(:slice_by_slice)

# note that by convention, Julia methods which 
# modify their arguments have names ending in "!"

```

Code continually reassigning `it` to the newest orange transformation isn’t particularly insightful. Waste of space and time.

> [@bertschi](#):
>
> Clojure also has chaining macros `->` and `->>` which pass the results of each function as the first and last argument respectively.

I didn’t know that about Clojure. Excellent example of a functional language implementing UFCS for the betterment of mankind.

As an aside, it’s an interesting idea to have syntax `->>` for inserting the object as the last argument. How frequently does this end up being used?

---

<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 8, 2022, 1:12am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/160 "2022-10-08T01:12:41Z")

</div>

Hah, the `--` operator is growing on me.

Dot `.` to get properties of this object; dash `--` to invoke methods on this object.

Not to be confused with Morse code.

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [October 8, 2022, 1:12am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/161 "2022-10-08T01:12:42Z")

</div>

> [@uniment](#):
>
> > [@bertschi](#):
> >
> > Clojure also has chaining macros `->` and `->>` which pass the results of each function as the first and last argument respectively.
> 
> I didn’t know that about Clojure. Excellent example of a functional language implementing UFCS for the betterment of mankind.

That’s not really UFCS: afaict, Clojure’s `->` is Chain.jl’s `@chain`, and `->>` is requested in [Macro to pass last argument · Issue #48 · jkrumbiegel/Chain.jl · GitHub](https://github.com/jkrumbiegel/Chain.jl/issues/48)

---

<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 8, 2022, 1:27am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/162 "2022-10-08T01:27:47Z")

</div>

> [@jar1](#):
>
> That’s not really UFCS: afaict, Clojure’s `->` is Chain.jl’s `@chain`, and `->>` is requested in [Macro to pass last argument · Issue #48 · jkrumbiegel/Chain.jl · GitHub](https://github.com/jkrumbiegel/Chain.jl/issues/48)

Fair. It’s as close to UFCS as you’ll get for a LISP.

Point is that they felt it wise to insert the object as the first argument in a similar fashion to UFCS.

---

<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 8, 2022, 8:05am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/163 "2022-10-08T08:05:56Z")

</div>

In Clojure all sequence functions, i.e., `map, filter` and friends take the sequence argument in the last position and `->>` is handy for pipelines in that case, i.e., `(->> (range 10) (filter even?) (map double))`. Maybe less useful in Julia and in any case [transducers](https://clojure.org/reference/transducers) have superseded much of the use for it in Clojure and Julia has a package for that as well [Transducers.jl](https://github.com/JuliaFolds/Transducers.jl).

For what it’s worth, what about this syntax using `@chain`?

```julia
using Chain

°°(x) = x # Unfortunately, -- is invalid syntax

@chain orange °° peel!(:fingertips) °° split!() °° put!(:bowl) °° eat!(:slice_by_slice) 

```

It’s funny that UFCS is actually coming to functional programming language given that the history in Lisp had been the reverse:

- Multiple Lisp dialects explored OOP – with fancy dynamic features such as whoppers or flavors – in the 80s and beginning of 90s, e.g., using a syntax such as `(send obj ':method args...)` (see for example [Flavors](https://www.softwarepreservation.org/projects/LISP/MIT/nnnfla1-20040122.pdf))
- In turn, this was considered awkward and at odds with the usual function syntax and changed into `(method obj args...)` paving the way for multiple-dispatch as the first argument no longer appeared special and eventually standardized in CLOS – the Common Lisp Object System.

I.e., syntax is important and can suggest novel ideas if approached open minded. Imho generic functions with multiple dispatch feel much more natural and allow for impressively reusable code. Message-passing OOP arguably still struggles to deliver on its promises here and I keep hitting roadblocks in those languages, but maybe it’s just me.

---

<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 8, 2022, 9:40am UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/164 "2022-10-08T09:40:27Z")

</div>

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). Anyway, if this feature is intended, we need to modify how frontend lowers this expression…

For example, in this new syntax, we have:

```julia
map(x->>x+y, array->push!(1)->push!(2)->vcat([1,2,3]))

```

Since `->` is used also in C/C++, I think this syntax is more acceptable than other notation (except for `.`, but we can’t use this symbol, it’s ready abused).

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [October 8, 2022, 1:33pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/165 "2022-10-08T13:33:44Z")

</div>

> [@uniment](#):
>
> Actually, `x--f(y)` meaning `f(x, y)` brings the benefit of encouraging what is frequently the most reasonable argument ordering, just as it’s reasonable for the subject of a sentence to precede the verb and predicate. At least that’s the case in the spoken languages I know.

In Julia, many data processing functions take the “object” they act on as the last argument, not the first. Both in Base (eg `map`, `filter`, …), in stdlib (eg `Iterators` equivalents), and across the ecosystem. Such functions are one of the most natural ones to use in multistep pipelines, so “pass the object as the first argument” often isn’t what one needs. Moreover, many of these functions take another “lambda” function as an argument.

In my opinion, [DataPipes.jl](https://gitlab.com/aplavin/DataPipes.jl) nicely addresses this common pipeline usecase. It puts the “object” as the last argument by default, and makes writing lambda functions more convenient. _disclaimer: author of datapipes_

Does this convenience issue - that can easily be solved in a package - really warrant a syntax change in Julia?

---

<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 8, 2022, 2:04pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/166 "2022-10-08T14:04:10Z")

</div>

Indeed, the last argument is often more convenient in functional languages, especially in combination with partial application or currying:

```julia
partial(f, args...) = (more...) -> f(args..., more...)

[1,2,3,4] |> partial(filter, iseven) |> partial(map, partial(*, 2)) |> sum

```

In this case, no new syntax is necessary as everything is just function call. Furthermore, it’s just a small steps towards [tacit programming](https://en.wikipedia.org/wiki/Tacit_programming)

```julia
∘̈(f, g) = g ∘ f

pipeline = partial(filter, iseven) ∘̈ partial(map, partial(*, 2)) ∘̈ sum
pipeline([1, 2, 3, 4])

```

and who wouldn’t love that 😉

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [October 8, 2022, 2:06pm UTC](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051/167 "2022-10-08T14:06:27Z")

</div>

Sure, it’s possible! But isn’t exactly convenient or easy to read.

Btw, your `partial()` is basically `Base.Fix1` for simple cases of only two arguments.

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

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