# Position-based Inline syntax for Curry

I would like to update an existing pseudo-curry function:

• /: h_[pre___, •, post___] :=
Function[expr, h[pre, expr, post]];


that I use inline like this - the bullet (option-8 on most keyboards) can be placed in any position:

{{1, 2}, {3, 4}} // Map[f, •, {2}]


{{f[1], f[2]}, {f[3], f[4]}}

This doesn't evaluate with HoldAllComplete functions like Lookup:

<|"a" -> 1, "b" -> 2|> // Lookup[•, "c", 0]


..."The argument Function[expr$,expr$] is not a valid Association or a \ list of rules"...

Curry on the other hand works, but requires a position spec:

<|"a" -> 1, "b" -> 2|> // Curry[Lookup, {3, 1, 2}]["c", 0]


0

Is there a convenient method to convert the sequence:

h_[pre___, •, post___]


Into the position options for curry, in the example {3,1,2}? I tried the fragment (using o rather than bullet here):

f[o, x, z] //
Replace[f_[pre___, o_, post___] :>
Map[Position[f[pre, o, post], #] & , List[post]]]// Flatten


{2,3}

Since the positions {2,3} correspond to just the post sequence and need to be shifted down to {1,2} and then combined with the pre part (here empty) this seems a long way to go.

Is there a cleaner approach?

EDIT

To summarize, Curry, unlike my pseudo-curry, works with HoldAllComplete functions, but requires numerical arguments to specify slots.

At least for the simple case of a single slot (as per my pseudo-curry), the inline position-based syntax is more usable.

So it's a matter of converting the pre___ and post___ to Curry numerical arguments.

Please pardon me if I fail to grasp the actual meaning of your question, however I don't see how a more complicated syntax can be avoided (by using a position, etc.) when working with a HoldAllComplete function.

If the idea is to not have to manually destructure the expression the cleanest solution I can see is something like:

Attributes[f] = HoldFirst;
f[h_[pre___, •, post___]] := Function[expr, h[pre, expr, post]]

<|"a" -> 1, "b" -> 2|> // f @ Lookup[•, "c", 0]               (* output: 0 *)


This is no better than using Function directly however, i.e. Lookup[#, "c", 0] &, which is why I think I may be missing the point.

Attempting to answer your question directly consider Ordering:

Attributes[ord] = HoldAllComplete;

ord[h_[arg___]] :=
Block[{•}, Replace[Hold[arg], {• -> 1, _ -> 0}, {1}]] // Ordering // Ordering

ord @ Lookup[•, "c", 0]

{3, 1, 2}

• Curry is new in 11.3: reference.wolfram.com/language/ref/Curry.html – Kuba Mar 25 '18 at 10:39
• @Kuba Thanks; I wondered about that. Since I'm not yet familiar with it do you think it has a place here? I mean is there a point to generating a position specification rather than the more direct approach? – Mr.Wizard Mar 25 '18 at 10:40
• Sorry, can't focus on this topic right now. Originally I was confused too that is why I didn't say anything about the case. – Kuba Mar 25 '18 at 11:07
• @Mr.Wizard, Curry definitely has a place here, precisely because it can curry HoldAllComplete functions. But it requires numerical arguments to specify slots, whereas at least for the simple case of a single slot (as per my pseudo-curry), the inline position-based syntax is more usable. So it's a matter of converting the pre___ and post___ to Curry numerical arguments. Will update my Q with this comment. – alancalvitti Mar 25 '18 at 16:46
• @alancalvitti Alright. I'll have to read about Curry at some point. For now does my answer solve your problem? Also do you find use in my f construct which also works with HoldAllComplete functions, at least in the manner shown? – Mr.Wizard Mar 26 '18 at 11:29