7
$\begingroup$

The Attributes function itself has the attributes:

Attributes[Attributes] 
{HoldAll,Listable,Protected} 

In particular, it is Protected which prevents me from redefining it:

Attributes = Foo 
During evaluation of In[2]:= Set::wrsym: Symbol Attributes is Protected. >> Foo 

however, I am able to modify Attributes if I associate to a symbol:

Attributes[Foo] = {Protected} 
{Protected} 

which seems strange to me, because other functions which are Protected can't do this. For example, with this newly protected Foo function, the following fails:

Foo[a] = 5 
During evaluation of In[5]:= Set::write: Tag Foo in Foo(a) is Protected. >> 5 

So how does the Protected attribute really work, and what makes the situation with the Attributes function different from my simple Foo function? Is it possible to have Foo work in the same way as Attributes?

$\endgroup$

1 Answer 1

5
$\begingroup$

It is because Attributes have UpValues(*) associated with them so at the end you are not trying to Set to Attributes[Foo] but it will be translated.

You can mimic that with e.g. UpSetDelayed (^:=):

ClearAll[f] Set[f[x_], attr_] ^:= SetAttributes[x, attr]; SetAttributes[f, {Protected, HoldFirst}] 

f = 2 
Set::wrsym: Symbol f is Protected. >> 
f[x] = HoldFirst (*no error*) Attributes[x] 
{HoldFirst} 

(*) Though I'm not sure if that is indeed the functionality used since <<GeneralUtilities` and PrintDefinitions @ Attributes shows something like _[___, Attributes, ___] := <<kernel function>>;. It's probably done in a slightly different way, not accesible to user(?), but I believe my point is valid.

$\endgroup$
1
  • $\begingroup$ Thanks for that! I originally figured it could be to do with Set, but I had no idea that it could be used in this way. $\endgroup$ Commented Apr 27, 2016 at 6:36

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.