[Date Index]
[Thread Index]
[Author Index]
Re: Implementing a array assignment for custom data structure
*To*: mathgroup at smc.vnet.net
*Subject*: [mg88915] Re: Implementing a array assignment for custom data structure
*From*: Szabolcs Horvát <szhorvat at gmail.com>
*Date*: Wed, 21 May 2008 14:50:02 -0400 (EDT)
*Organization*: University of Bergen
*References*: <g0tqub$mj9$1@smc.vnet.net>
Salvatore Mangano wrote:
> Lists support a convenient syntax for element assignment:
>
> a[[i]]=v
>
> Of course this syntax is syntactic sugar for:
>
> Set[Part[a, i], v]
>
>
> SparseArray's have a different structure than lists but still support the same syntax.
>
> This leads me to believe that I should be able to implement a custom type (akin to SparseArray) that also allows this syntax (possibly using UpValues) but for the life of me I can't see how to accomplish this.
>
> Any ideas?
One is always reluctant to say that something is impossible because of
the possibility of being proven wrong ... but I believe that this cannot
be done.
Here are a few examples to demonstrate why. I shall use the symbol part
instead of Part (because I do not want to assign rules to Part).
Let the custom data structure be myList, whose argument is a normal List.
SetAttributes[myList, HoldAll]
l = {1, 2, 3}
x = myList[l]
We shall consider the nth element of x to be equivalent to the nth
element of l. We want to allow setting e.g. the 2nd element of x to 5
with the following command: part[x, 2] = 5
The implementation that might spring to mind first is
myList /: Set[part[myList[a_], n_], val_] := (a[[n]] = val)
But this does not work. The reason is that myList is 2 levels deep
inside the pattern, so an UpValue cannot be assigned to it.
We need to assign the UpValue to part. Unfortunately this is already a
problem, because one does not feel safe modifying Part ...
The next try could look like this
part /: Set[part[myList[a_], n_], val_] := (a[[n]] = val)
But this still does not work ... It turns out that the reason is that
Set is HoldFirst, so Set[part[x,2], 5] keeps x unevaluated (and it
cannot match myList).
Here's a fairly complicated version that does work:
part /: Set[part[ml_ /; Head[ml] === myList, n_], val_] :=
Extract[ml, 1, Function[{lst}, lst[[n]] = val, {HoldAll}]]
(The complicated RHS is for extracting the argument of the myList object
without actually evaluating it. It is not really relevant for the example.)
So it seems that what you are asking for can only be accomplished by
modifying Part or Set. I strongly recommend against attempting anything
like this. Also note that sparse arrays are treated specially by
Mathematica. They are considered atoms (AtomQ returns True), and many
structure manipulation functions beside Part work on them (e.g. Map, etc.)
Prev by Date:
**Re: Labeling points**
Next by Date:
**Re: Problems with ListPlot**
Previous by thread:
**Re: Implementing a array assignment for custom data structure**
Next by thread:
**Problems with ListPlot**
| |