23
$\begingroup$

I find it tedious to write out the following:

a = {1, 2, 3, 4};

Fold[f, First @ a, Rest @ a]
f[f[f[1, 2], 3], 4]

It becomes additionally cumbersome when working with held expressions, e.g.:

b = Hold[1 + 1, 2 + 2, 3 + 3, 4 + 4];

SetAttributes[g, HoldAll];

b /. _[x_, __] :> Fold[g, Unevaluated[x], Rest@b]
g[g[g[1 + 1, 2 + 2], 3 + 3], 4 + 4]

Likewise for FoldList. Is there a shorter syntax to achieve this?

$\endgroup$

1 Answer 1

28
$\begingroup$

Good News Everyone!

Two-parameter syntax for Fold and FoldList has been (silently) implemented!

Taliesin Beynon informs me that this was implemented in 2011, so check your older versions as well.

As Naitree notes this is now documented in 10.0.2:

enter image description here enter image description here

Fold[f, a]

FoldList[f, a]
f[f[f[1, 2], 3], 4]

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

And the held expression example:

Fold[g, b]
g[g[g[1 + 1, 2 + 2], 3 + 3], 4 + 4]

For full integration (versions 9.0 through 10.0.1) we merely need to update SyntaxInformation to match the implementation:

Unprotect[Fold, FoldList]

SyntaxInformation[Fold]     = {"ArgumentsPattern" -> {_, _, _.}};
SyntaxInformation[FoldList] = {"ArgumentsPattern" -> {_, _., {__}}};

Protect[Fold, FoldList]

(We could also update usage Messages if desired, but not doing so serves as a reminder that the function is undocumented in these versions.)

For older versions you may add the functionality itself with:

Unprotect[Fold, FoldList]

Fold[f_, h_[a_, b__]]     := Fold[f, Unevaluated @ a, h @ b]
FoldList[f_, h_[a_, b__]] := FoldList[f, Unevaluated @ a, h @ b]

Protect[Fold, FoldList]

Special thanks to those who made this happen!

$\endgroup$
17
  • 6
    $\begingroup$ @Mr.Wizard, I thought we had a discussion about it a while back - perhaps I forgot to mention that I could sneak it in;-) I am glad you like it. $\endgroup$
    – user21
    Commented Jul 14, 2014 at 8:33
  • 2
    $\begingroup$ @YiWang, I think, IIRC, it works from V9 onward. $\endgroup$
    – user21
    Commented Jul 14, 2014 at 8:51
  • 1
    $\begingroup$ @Naitree I'll tell you what I do. I use a single line in init.m to load a package which contains my own functions and customizations. This makes it easy to "comment out" that line if needed. I create, update, and manage the .m package file from a companion Notebook (.nb) with Initialization Cells; when you save such a Notebook for the first time it should ask you if you want to create a Package. I save this Notebook/Package to the Applications directory under $UserBaseDirectory. (continued) $\endgroup$
    – Mr.Wizard
    Commented Oct 25, 2014 at 5:00
  • 1
    $\begingroup$ For modifications to System` symbols you do not need to create a new Context but for your own functions I believe that you should. However be aware that this can complicate access to your own functions from Cell contexts etc.; see: (9571) and (13293). Let me know if you run into any problems and I'll try to help, or just post a Question about it. $\endgroup$
    – Mr.Wizard
    Commented Oct 25, 2014 at 5:01
  • 1
    $\begingroup$ @Naitree By the way: be careful with modifying System functions. There is a reasonable school of thought that says you should never do it. There are usually alternatives, e.g. one could create a MyTools`Fold function and let this supersede the System`Fold function for interactive input. Also be aware that in some cases your modifications may be undone by internal (re)loading; see: (32531), (63656). $\endgroup$
    – Mr.Wizard
    Commented Oct 25, 2014 at 5:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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