8
$\begingroup$

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.

$\endgroup$
1
$\begingroup$

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}
$\endgroup$
  • 1
    $\begingroup$ Curry is new in 11.3: reference.wolfram.com/language/ref/Curry.html $\endgroup$ – Kuba Mar 25 '18 at 10:39
  • $\begingroup$ @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? $\endgroup$ – Mr.Wizard Mar 25 '18 at 10:40
  • $\begingroup$ 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. $\endgroup$ – Kuba Mar 25 '18 at 11:07
  • $\begingroup$ @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. $\endgroup$ – alancalvitti Mar 25 '18 at 16:46
  • $\begingroup$ @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? $\endgroup$ – Mr.Wizard Mar 26 '18 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.