MathGroup Archive 2011

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Assigning part of indexed object

  • To: mathgroup at
  • Subject: [mg119863] Re: Assigning part of indexed object
  • From: Oleksandr Rasputinov <oleksandr_rasputinov at>
  • Date: Sun, 26 Jun 2011 06:26:49 -0400 (EDT)
  • References: <itsjn7$8u7$> <iu49sb$jp7$>


I fully agree with all of your comments and of course you are right to
point out that modifying core functions such as Set is a bad idea in
general due to the likelihood of unintended consequences. Of course,
the performance issue introduced for setting parts of OwnValues can
be repaired to some extent:

indexedQ = Function[sym,
   Symbol =!= Head@Unevaluated[sym] =!= Unevaluated[sym],

Set[(sym_?indexedQ)[[part_]], val_] := (
   sym = ReplacePart[sym, part -> val];

which restores the O(1) behaviour (albeit at the cost of an increased
constant factor). But even so, I will join with you in stressing that this
general approach is dangerous and should be attempted only with
extreme caution, if at all.


O. R.

On Jun 25, 10:30 am, Leonid Shifrin <lsh... at> wrote:
> Hi Fabrice,
> My guess is that the reasons are efficiency and immutability of  expres=
> in Mtahematica. By restricting Set
> to variables or array elements, one can connect it directly to the intern=
> memory layout for that element. Note
> that all proposed solutions are based on ReplacePart, which copies the
> entire list to modify a single element.
> OTOH, constructs like indexed variables are serviced by hash-tables
> internally. Even if the value stored
> in the hash table is a pointer to some array, that array will likely be
> immutable. Whether it would be a
> good idea to make it mutable I don't know, but the general ideology is th=
> expressions are immutable
> in Mathematica. In other words, I don't think that the case of indexed
> variables was overlooked when
> designing Set - my guess is that the restriction to symbols is quite
> intentional.
> Regarding the "fix", I'd consider this not a fix but  a recipe for disa=
> because modifying Set in such
> a fashion is  dangerous, not to mention that it will often be completel=
> unacceptable performance-wise. Let us say
> you store a large array in a symbol and use a For loop with array indexin=
> Suddenly all your array element assignments
> become O(n) time, where n is the list size, or even worse for higher
> dimensional tensors, not to mention increased
> memory consumption. Here is an illustration:
> In[18]:= a = Range[10000];
> In[19]:= Unprotect[Set];
> Set[sym_[[part_]], val_] := sym = ReplacePart[sym, part -> val];
> Protect[Set];
> In[27]:= Do[a[[i]] = a[[i]]^2, {i, Length[a]}] // Timing
> Out[27]= {1.156, Null}
> In[28]:= Unprotect[Set];
> Clear[Set];
> Protect[Set];
> In[31]:= Do[a[[i]] = a[[i]]^2, {i, Length[a]}] // Timing
> Out[31]= {0.047, Null}
> You may do this for  yourself if you wish (although I'd avoid even that=
> but I'd strongly
> advise against such modifications in production code or any code someone
> else will be using. Set is one of the
> most fundamental operations, and its modifications may have very far-
> reaching and hard to predict consequences.
> It may, for example, corrupt the system in very subtle ways, which you ma=
> never be able to identify.
> Unfortunately, the standard mechanism of "soft" system symbols overloadin=
> via UpValues does not
> quite work with Set (or at least I don't know of a way to make it work)
> because Set holds its argument and UpValues
> can only be defined for tags not deeper than level 1 in an expression. In
> this post:
> I demonstrated a method, which I also don't like, but which is at least
> safer because it tests for a
> specific data type. Generally, the still  safer way is to create your o=
> data type and introduce your own
> assignment operator(s) - in this way, you don't have to modify Set at all=

  • Prev by Date: Re: Date based calculations
  • Next by Date: Geolocation in Session Information Message
  • Previous by thread: Re: Assigning part of indexed object
  • Next by thread: Re: Assigning part of indexed object