# Left-associative Apply

Often I want a version of @ that is left-associative (might not be using that term correctly).

What I mean is I'd like some operator l@ such that:

a l@ b l@ c === a[b][c]


Standard @ gives us:

a @ b @ c === a[b[c]]


Is there such an operator I've overlooked? (I don't want to use brackets on brackets on brackets)

• – M.R. Jan 23 '19 at 6:54
• – M.R. Jan 23 '19 at 6:55
• Interesting question, can it be that the documentation is wrong for Infix? According to documentation something like Infix[ f[a,b,c], "~", 490, Left ] is supposed to word but does not. The same syntax should also work for Prefix. – gwr Jan 23 '19 at 10:19
• Being pedantic, the title of the question isn't strictly correct: Apply is @@, not @. The operators @ and // are both called "function application" in the Docs. So more correct title would be "Function application with left-associative grouping". – Alexey Popkov Feb 11 '19 at 11:02

I am not aware of a built-in operator that will call a function with individual sub-value arguments (i.e. curried arguments).

The function Curry has a promising-sounding name, but it lifts a function that takes uncurried arguments into one that takes curried arguments -- sort of the opposite of what we want here.

We could define our own by pressing one of the operators without built-in meanings into service. Let's use CirclePlus (⊕) in one of the following ways:

CirclePlus[f_, r___] := Fold[Construct, f, {r}]


or prior to version 11.3:

CirclePlus[f_, r___] := Fold[#[#2]&, f, {r}]


or using the now undocumented function HeadCompose:

CirclePlus = HeadCompose;


With any of these, we can then write:

f⊕a

(* f[a] *)

f⊕a⊕b

(* f[a][b] *)

f⊕a⊕b⊕c

(* f[a][b][c] *)

f⊕a⊕b⊕c⊕d

(* f[a][b][c][d] *)

• As I noted in a comment to Carl Woll the issue is that I can't trust these operator forms to not have rules attached to them by someone else. I don't like to play with "System" level symbols since I can't scope them without potentially breaking someone else's code. What I had to do, inefficient though it is, was to simply attach a DownValue to my primary object that took a pattern like a["method"[]@["property"]] and rewrite it as a["method[]]@"property". As long as I use strings for method and property names there's no danger with premature evaluation here. – b3m2a1 Sep 13 '19 at 23:01
• @b3m2a1 I'm inclined to agree with you about overloading the operator forms. It is a powerful tool for project work... but use in library code is downright dangerous. – WReach Sep 13 '19 at 23:29

Another alternative is to use a built-in operator form that has left-associative grouping. A couple examples:

CircleMinus[a_, b_] := a[b]
a ⊖ b ⊖ c


a[b][c]

LeftTee[a_, b_] := a[b]
a ⊣ b ⊣ c


a[b][c]

• Thank you! I have been looking for a left-associative operator for a long time! I suppose that in order to fully emulate parsing behavior of @, it would be a good idea to add HoldAllComplete as well. Compare with and without HoldAllComplete: a[b] = HoldComplete; c = 1; a\[CircleMinus]b\[CircleMinus]c – Anton.Sakovich Jan 24 '19 at 8:13
• I'm always uncomfortable using these built-in operators because I don't want to take one out of commission for other people... On the other hand I can't just use my own symbol and attach a MakeBoxes rule to it because this needs to work inside a package -_- It's just too dangerous, though, to use one of these "System" level ones since there's no way to scope its effect. – b3m2a1 Sep 13 '19 at 23:00
• @b3m2a1 Would having an input alias work for you? Or does it have to be InputForm only because it's in a package? – Carl Woll Sep 17 '19 at 0:22
• It would be used in a package unfortunately. Realistically no one else will ever use it, probably, but I’d like to adhere to good development practices despite that. – b3m2a1 Sep 17 '19 at 0:24