4

How can we check if an entry to our function is a Function or a Pure Function?

For example:

FunctionQ[target_]:=...

FunctionQ[Function[x, x^2]] == True
FunctionQ[#^2&] == True
FunctionQ[x^2] == False

It looks like we don't have a FunctionQ method available on Mathematica.

The motivation is that I'd like to combine this with the answer of this question to create only one function for the accepted answer of that link.

Edit:

Combining the provided answer, it looks like we can do the following:

FunctionQ[expression_Function?System`Private`ValidQ] := True;
FunctionQ[___] := False;
Test[expression_, variable_Symbol] :=
  Block[
    {final},
    If[
     FunctionQ[expression],
     final = expression,
     final = Function[variable, expression]
     ]
    ][4];

Test[Function[x, x^2], x] (* 1 *)

Test[#^2 &, x] (* 2 *)

Test[x^2, x] (* 3 *)

f1 = x^2; Test[f1, x] (* 4 *)

f2[x_] := x^2; Test[f2, x] (* 5 *)

Test[f2[x], x] (* 6 *)


16 (* 1 *)

16 (* 2 *)

16 (* 3 *)

16 (* 4 *)

b (* 5 *)

16 (* 6 *)
GarouDan
  • 1,536
  • 1
  • 12
  • 15
  • Should FunctionQ[Log] return True? How about FunctionQ[Derivative[1][Zeta]] or FunctionQ[Hold]? – J. M.'s missing motivation Jun 07 '20 at 15:38
  • Interesting point. I'll check this more in depth and return. – GarouDan Jun 07 '20 at 15:44
  • For explicit functions (i.e., have the Head of Function) you can use a pattern like f[z_Function] := .... Then f[(#^2&)] or f[Function[{x},x^2]] would evaluate. – Bob Hanlon Jun 07 '20 at 15:54
  • Hum, this is interesting as well. – GarouDan Jun 07 '20 at 16:14
  • 2
    @GarouDan Out of curiosity, this and your other previous questions seemed to point to some odd requirements in your code. Since I have made the mistake of concentrating on fixing my proposed solution rather than refactoring the problem (a classic XY Problem), I like to ask: What is the final ultimate goal here? I.e. why do you need the functionality you are developing? I don't mean to say that there is anything wrong with your approach, it's just that one sometimes gets bogged down in the details of implementing the first solution that comes up, rather than thinking whether it is the best one. – MarcoB Jun 07 '20 at 19:30
  • 1
    maple has this build in actually. There is specific type called function. check type for function it is useful for parsing input for example. Mathematica should really have FunctionQ as well. – Nasser Jun 08 '20 at 06:56

1 Answers1

11

Observing the fact that valid Function objects seem to be marked as ValidQ we can use

FunctionQ[f_Function?System`Private`ValidQ] := True
FunctionQ[___] := False

Then use it via

In[100]:= FunctionQ[Function[{x, y}, x + 2]]

Out[100]= True

In[103]:= FunctionQ[# + 1 &]

Out[103]= True

In[105]:= FunctionQ[Log]

Out[105]= False

In[106]:= FunctionQ[Function[]]

During evaluation of In[106]:= Function::argb: Function called with 0 arguments; between 1 and 3 arguments are expected.

Out[106]= False
Jason B.
  • 68,381
  • 3
  • 139
  • 286
  • Oh, cool, clever solution. I'll check and return ;) – GarouDan Jun 07 '20 at 15:44
  • I think for my purposes it works fine ;), only one case above didn't work (please see my edit). If you know how could I solve it, please let me know ;) – GarouDan Jun 07 '20 at 16:22
  • One other thing that I'd like to ask. How did you find about SystemPrivateValidQ? I'd like to use this approach to find how the things are defined in Mathematica in the future? – GarouDan Jun 07 '20 at 17:23
  • @GarouDan you can use techniques such as Names[“System`*”] or related to find those sorts of things. Also try searching “spelunking tools” in the search bar here. And looking into the developer tools would be helpful, too. – CA Trevillian Jun 07 '20 at 20:34
  • @CATrevillian, unfortunately Names[“System*”]does not contain any reference toValidQ`. Also using the Mathematica search nothing appears. About searching here, I tried "spelunking tools" and it seems interesting, but I didn't find yet a place with a collection of these kind of tools to use. It would be very useful for me. – GarouDan Jun 08 '20 at 01:16
  • @GarouDan try exploring the private context, so using ”System`Private`*” within Names. I had given the truncated example in an attempt to be generalized, and also laziness when responding on mobile. As for using the search in the documentation center, I doubt you would find something of the nature of ValidQ. However, you might find some useful information using the developer tools to print the definition of the function/symbol/context you are interested in. – CA Trevillian Jun 08 '20 at 01:22
  • @GarouDan my deepest apologies. You want to use ”GeneralUtilities`” within Needs, as described here. – CA Trevillian Jun 08 '20 at 01:31
  • 1
    Indeed this is very interesting, we can get a lot of insights. But it still a mystery for me how @JsonB was able to find the ValidQ from the functions definitions. Specially when he says: Observing the fact that valid Function objects seem to be marked as ValidQ we can use – GarouDan Jun 08 '20 at 01:58
  • 1
    Search this site for ValidQ. People share insights here, which come from a variety of sources. I learned about ValidQ from a post on this site. – Michael E2 Jun 08 '20 at 04:29