23

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?

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371

1 Answers1

28

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!

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • Interesting! Thanks a lot for sharing! – Yi Wang Jul 14 '14 at 07:41
  • 6
    @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. – user21 Jul 14 '14 at 08:33
  • It already works in M9 (Feb 7 2013 build). – Yi Wang Jul 14 '14 at 08:36
  • @user21 I'm terribly sorry if I forgot or somehow confounded you with someone else. (I have a very poor memory as I keep telling people.) Many thanks for getting this done! – Mr.Wizard Jul 14 '14 at 08:48
  • 2
    @YiWang, I think, IIRC, it works from V9 onward. – user21 Jul 14 '14 at 08:51
  • @Mr.Wizard How can I save the custom definitions for built-in symbols permanently? Is it init.m the correct choice? I searched the site but maybe I just couldn't pick a right keyword to the answer. – Naitree Oct 25 '14 at 04:41
  • 1
    @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) – Mr.Wizard Oct 25 '14 at 05:00
  • 1
    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. – Mr.Wizard Oct 25 '14 at 05:01
  • 1
    @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). – Mr.Wizard Oct 25 '14 at 05:07
  • @Mr.Wizard Following your thorough instructions, I have successfully created a package file named CustomDefinitions.m under $UserBaseDirectory/Applications, and put <<CustomDefinitions/CustomDefinitions.m in the init.m file which is under $UserBaseDirectory/Kernel. However, strangely I found out that the init.m file won't load automatically when I restarted Mma. I mean, the init.m takes effect only if I manually kick <<init.m after a fresh start of Mma. Also, I have checked that the default contexts of both init.m and Untitled-1 are Global. Any suggestions? – Naitree Oct 25 '14 at 16:48
  • @Naitree Strange that your Kernel/init.m file isn't auto-loading. It is possible to suppress loading with kernel launch flag -noinit as can be set from Kernel Configuration Options... but you would probably remember if you had set that. If the problem persists I suggest you post a Question about it as other people may have more ideas. (I cannot recall having that problem.) Side note: it should be sufficient to use <<CustomDefinitions.m to load your package from that path as it should be in the $Path list. – Mr.Wizard Oct 25 '14 at 19:44
  • @Mr.Wizard I realized that init.m is evaluated automatically when the first input line of the session is being sent to the kernel. Not immediately after system start-up. So I think it actually works fine... :-) – Naitree Oct 26 '14 at 12:19
  • @Naitree Ah, that's correct. It is evaluated every time a kernel (without -noinit) is started, so if you terminate and restart a kernel or launch a new one your definitions should be loaded. – Mr.Wizard Oct 26 '14 at 21:05
  • 1
    Hi again, @Mr.Wizard. I found out that two-argument form of Fold and FoldList has been offically documented in 10.0.2. See details section of their docs. :) – Naitree Dec 17 '14 at 03:11
  • @Naitree Thanks for the note! – Mr.Wizard Dec 17 '14 at 03:36
  • @user21 Is there now any reason not to implement an operator form for Fold such that Fold[fn][list] is equivalent to Fold[fn, list]? – Mr.Wizard Jan 02 '15 at 02:31
  • @Mr.Wizard, I was not involved in the operator form implementation, but I'll forward that as a suggestion. – user21 Jan 02 '15 at 11:03