11
$\begingroup$

This question already has an answer here:

In version 10 some built-in symbols are updated to support operator form like the Derivative. For example, Select, Cases, MatchQ, Map-related functions, and so on. These updates are handy (although it is not clear whether they are directly defined as SubValues for the symbols or defined as functions, see this answer.)

In principle we can check all the new symbols listed here to see which of them have operator form. But this is tedious. Is there a way to automatically return such symbols from Names["System`*"]? The difficulty is, neither DownValues nor SubValues can be used to built-in symbols to return useful information.

$\endgroup$

marked as duplicate by Szabolcs, Yves Klett, user31159, Feyre, m_goldberg Oct 30 '16 at 21:01

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    $\begingroup$ It is not only functions (Symbols) introduced in version 10 that may have operator forms; very old functions like Map do too. I do not know how to check a Symbol for such a syntax directly and I fear that the documentation is not consistent enough to use detection of the phrase "operator form" for robust determination. $\endgroup$ – Mr.Wizard May 21 '15 at 16:56
  • $\begingroup$ @Mr.Wizard, I will be glad to know any possible method that can do this. However I am also glad to know that this is not feasible by using the Wolfram Language alone without help from "external intelligence" (i.e., manual check). In fact the latter case would be a good example for the Godel's incomplete theorem, which states that any consistent system that is general enough to include elementary arithmetic is not complete. I.e., there are always true statements not provable from within such consistent system. To prove these statements we need "external intelligence" outside from the system. $\endgroup$ – saturasl May 21 '15 at 17:29
  • 1
    $\begingroup$ Note that you could conceivably use SyntaxInformation on Names["System`*"] and then check which of the function that allow a single-argument spec return unevaluated (i.e. in an operator form) without a message when given a single argument, like Map[#&] does now. $\endgroup$ – Stefan R May 21 '15 at 19:39
  • 3
    $\begingroup$ @Stefan That assumes that all operator forms have a single parameter when in fact they do not; for example: Insert[elem,pos] represents an operator form of Insert that can be applied to an expression. and MapAt[f,pos] represents an operator form of MapAt that can be applied to an expression. $\endgroup$ – Mr.Wizard May 22 '15 at 8:46
  • 5
    $\begingroup$ Related: mathematica.stackexchange.com/questions/60045/… $\endgroup$ – Michael E2 Dec 27 '15 at 1:23
9
$\begingroup$

My own documentation-based approach using usage messages:

file = FileNameJoin[{$InstallationDirectory, "SystemFiles", "Kernel", 
        "TextResources", $Language, "Usage.m"}];

usage = Import[file, "HeldExpressions"];

usage //
  Cases[
    HoldPattern[
      _[_[sym_Symbol, "usage"] = _String?(StringContainsQ["operator form"])]
    ] :> sym
  ]

Output:

{AllTrue, AnyTrue, Append, Apply, AssociationMap, Cases, CellularAutomaton,
CountDistinctBy, CountsBy, Count, DeleteCases, DeleteDuplicatesBy, Delete, Extract,
FirstCase, FirstPosition, FreeQ, GroupBy, Insert, KeyDrop, KeyExistsQ, KeyMap, KeySelect,
KeySortBy, KeyTake, KeyValueMap, Lookup, MapAt, MapIndexed, Map, MatchQ, MaximalBy,
MemberQ, Merge, MinimalBy, NoneTrue, Position, Prepend, ReplacePart, Replace, Scan,
SelectFirst, Select, SortBy, StringCases, StringContainsQ, StringDelete, StringEndsQ,
StringStartsQ, TakeLargestBy, TakeLargest, TakeSmallestBy, TakeSmallest}

This returns fewer items than Michael's method which also includes:

{Dataset, NDSolve, NDSolveValue, Query}

Michael notes that NDSolve and NDSolveValue are false-positives and I would argue that Dataset and Query are special cases so I guess my output is as good as we have so far.

$\endgroup$
  • $\begingroup$ +1. Those middle two missing items don't really count. Or rather, it's better that they are omitted. $\endgroup$ – Michael E2 May 21 '15 at 18:50
  • $\begingroup$ @MichaelE2 I was just checking the complement and I conclude that they are all reasonable omissions, so usage messages seem a good start. Now, are there any known operator forms that are missing from this list? $\endgroup$ – Mr.Wizard May 21 '15 at 18:54
  • $\begingroup$ None that I can spot, but that's not saying much. What's missing is the fault of WRI: Take, Drop, perhaps others that haven't been implemented. (Note Take[list] returns list, but why is that behavior worth saving? Maybe because of Take[list, seq1, seq2],...] I suppose.) $\endgroup$ – Michael E2 May 21 '15 at 19:06
  • $\begingroup$ @Mr.Wizard As always I learn useful knowledge from you, concise yet rich when digested. Thank you for your attention. $\endgroup$ – saturasl May 22 '15 at 5:41
  • $\begingroup$ @saturasl Thanks for the Accept. If I discover any that are missing from this list I shall try to remember to add them. $\endgroup$ – Mr.Wizard May 22 '15 at 8:47
12
$\begingroup$

As Mr.Wizard already noted, it's not clear whether "operator form" occurs in the documentation of every command that has an operator form (or conversely, e.g., NDSolve*, which references the operator form of Inactive).

docdir = FileNameJoin[{$InstallationDirectory, "Documentation", 
    "English", "System", "ReferencePages", "Symbols"}];
docs = FileNames["*", docdir];

ops = Count[Get[#], 
    s_String /; StringMatchQ[s, ___ ~~ "operator form" ~~ ___], 
    Infinity] & /@ docs

ToExpression @ Pick[StringDrop[#, -3] & /@ FileNameTake /@ docs, Unitize[ops], 1]
(*
{AllTrue, AnyTrue, Append, Apply, AssociationMap, Cases, \
CellularAutomaton, CountDistinctBy, Count, CountsBy, Dataset, \
DeleteCases, DeleteDuplicatesBy, Delete, Extract, FirstCase, \
FirstPosition, FreeQ, GroupBy, Insert, KeyDrop, KeyExistsQ, KeyMap, \
KeySelect, KeySortBy, KeyTake, KeyValueMap, Lookup, MapAt, \
MapIndexed, Map, MatchQ, MaximalBy, MemberQ, Merge, MinimalBy, \
NDSolve, NDSolveValue, NoneTrue, Position, Prepend, Query, Replace, \
ReplacePart, Scan, SelectFirst, Select, SortBy, StringCases, \
StringContainsQ, StringDelete, StringEndsQ, StringStartsQ, \
TakeLargestBy, TakeLargest, TakeSmallestBy, TakeSmallest}
*)

On a Unix system, you can do this:

commandstring = "!cd " <> docdir <> "; fgrep -l \"operator form\" *";
StringDrop[#, -3] & /@ Import[commandstring, "List"] // ToExpression
$\endgroup$
  • $\begingroup$ For what it's worth StringContainsQ is a slightly cleaner method. (+1) $\endgroup$ – Mr.Wizard May 21 '15 at 18:47
  • $\begingroup$ @Mr.Wizard Oh my, so many new String*Q commands. Looks like they forgot StringContainsExactlyOnceQ. Oh well. (As a string version of MemberQ, I approve, in fact. Should have called it StringMemberQ, though, imo.) $\endgroup$ – Michael E2 May 21 '15 at 18:57
  • $\begingroup$ Funny, I also thought it should have been StringMemberQ for consistency. $\endgroup$ – Mr.Wizard May 21 '15 at 18:58
  • $\begingroup$ @Michael E2 Brilliant! We let Mathematica examine its own documentation as external sources and search for the key word. I would have considered using python for this, but your alternative script is even better, because it shows the potential to use Wolfram Language to do big things in scientific computing, which for now is still domanined by python together with C++. The first answer clearly attributes to you, while the improved answer from Mr.Wizard can offer better performance and accuracy. For this reason I mark Mr.Wizard's answer as the best answer, but you have my sincere thanks. $\endgroup$ – saturasl May 22 '15 at 5:29
  • $\begingroup$ @saturasl Thanks & you're welcome. I was hoping you would accept Mr.Wizard's answer, as I think it is better, too. $\endgroup$ – Michael E2 May 22 '15 at 9:54

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