views:

128

answers:

3

I need a function that takes the name of a symbol as a string and returns whether that symbol is already defined. The function ValueQ is close but it returns False for function names. Also, it takes symbols rather than strings.

Examples:

defined["N"] --> True (predefined function N)
defined["x"] --> False
x = 7;
defined["x"] --> True (x is now defined)
defined["7"] --> True (7 is a number)
f[x_] := 2x
defined["f"] --> True (f has DownValues)
g[x_][y_] := x+y
defined["g"] --> True (g has SubValues)

PS: Thanks to Pillsy for pointing out the need to check for both DownValues and SubValues.

+1  A: 

I think Names should do the trick:

Names["string"] gives a list of the names of symbols which match the string.

If Names["foo"] returns {}, then there should be no definitions for foo, otherwise it should return {"foo"}. So your function 'defined' might be done as:

defined[str_] := Names[str] != {}

For symbols at least, because this doesn't work for "7", since 7 is not a symbol. You could handle this case seperately, for instance with NumberQ.

Also, you can use Symbol to make a symbol out of a string (useful for automatically generating symbols) and Definition to check the definitions of a symbol.

Symbol["name"] refers to a symbol with the specified name.

Definition[symbol] prints as the definitions given for a symbol.

EDIT: Better than looking at what Names returns, NameQ["name"] tells you if a given name exists. Still doesn't tell you if the symbol has an explicit definition though, just that it has been mentioned.

Joren
Oh, nice! It fails for Names["7"] though. Also, if you so much as mention a symbol x then Names["x"] will indicate it's defined even if it actually has no definition.
dreeves
You're right. I'm not sure if there is any way to know if a symbol has an explicit definition or it was only mentioned. Definition[foo] tells you this, but can't be used automatically I think.
Joren
A: 

I cobbled this together, which seems to work:

defined[s_] := ToExpression["ValueQ[" <> s <> "]"] || 
               Head@ToExpression[s] =!= Symbol || 
               ToExpression["Attributes[" <> s <> "]"] =!= {} ||
               ToExpression["DownValues[" <> s <> "]"] =!= {} ||
               ToExpression["SubValues[" <> s <> "]"] =!= {}

Hopefully there's a prettier solution.

PS: Thanks to Pillsy for pointing out the need to check for both DownValues and SubValues.

dreeves
+1  A: 

You can use DownValues to see if you have "functions" associated with a symbol. This will work for definitions like

f[x_, y_] := x + y

or

g[3] = 72 * a;

It won't work for exotic things like

h[a_][b] = "gribble";

but most people won't think of that as defining a function anyway. If you want to check for the existence of a function definition, you need to convert the name to an expression (and make sure it's wrapped in Hold when you do!). Here's a reasonably robust function that checks for both DownValues and SubValues:

functionNameQ[name_String] := 
    With[{ hSymbol = ToExpression[name, InputForm, Hold] },
        MatchQ[hSymbol, Hold[_Symbol]] &&
            ((DownValues @@ hName) =!= {} || (SubValues @@ hName) =!= {})];
Pillsy