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$ Commented Jul 14, 2014 at 8:33
  • 2
    $\begingroup$ @YiWang, I think, IIRC, it works from V9 onward. $\endgroup$ 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$ 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$ 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$ Commented Oct 25, 2014 at 5:07

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.