Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

# part assigned sequence behavior puzzling

34 views

### mkr

Nov 25, 2009, 2:31:25â€¯AM11/25/09
to
I am puzzled by the following behavior:

tmp = Range[15]
tmp[[7]] = Sequence @@ Range[2];
tmp[[7]] = Sequence @@ Range[2];
tmp[[7]] = Sequence @@ Range[2];
tmp

yields

{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
{1, 2, 3, 4, 5, 6, 1, 2, 8, 9, 10, 11, 12, 13, 14, 15}

I would have expected the repeated assignment to have a repeated
effect, thus obtaining

{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
{1, 2, 3, 4, 5, 6, 1, 2, 2, 2, 8, 9, 10, 11, 12, 13, 14, 15}

Where/why am I wrong?

### Sjoerd C. de Vries

Nov 25, 2009, 6:22:32â€¯AM11/25/09
to
I don't think you're wrong. I was just as puzzled with this behaviour
as you. I'd say it's a bug. Just look at the following :

Using extra temporary variables works as expected:

In[283]:= tmp = Range[15];

tmp[[7]] = Sequence @@ Range[2];

tmp2 = tmp;
tmp2[[7]] = Sequence @@ Range[2];
tmp3 = tmp2;
tmp3[[7]] = Sequence @@ Range[2];
tmp3

Out[289]= {1, 2, 3, 4, 5, 6, 1, 2, 2, 2, 8, 9, 10, 11, 12, 13, 14, 15}

Using different locations in tmp works as expected:

In[295]:= tmp = Range[15];
tmp[[3]] = Sequence @@ Range[2];
tmp[[5]] = Sequence @@ Range[2];

tmp[[7]] = Sequence @@ Range[2];
tmp

Out[299]= {1, 2, 1, 2, 4, 1, 2, 6, 1, 2, 8, 9, 10, 11, 12, 13, 14, 15}

Temporarily storing tmp somewhere else works as expected:

In[311]:= tmp = Range[15];

tmp[[7]] = Sequence @@ Range[2];

tmp2 = tmp;
tmp = 0;
tmp = tmp2;

tmp[[7]] = Sequence @@ Range[2];

tmp2 = tmp;
tmp = 0;
tmp = tmp2;

tmp[[7]] = Sequence @@ Range[2];
tmp

Out[321]= {1, 2, 3, 4, 5, 6, 1, 2, 2, 2, 8, 9, 10, 11, 12, 13, 14, 15}

My original hypothesis of what happens here was that Mathematica
optimizes assignments and remembers what it last assigned to a
location in an array. If it is the same, it does nothing. This would
work for all elements except Sequence.

This hypothesis is falsified by the following tests in which I changed
the ranges:

In[392]:= tmp = Range[15];

tmp[[7]] = Sequence @@ Range[2];

tmp[[7]] = Sequence @@ Range[3];
tmp[[7]] = Sequence @@ Range[4];
tmp

Out[396]= {1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 14, 15}

In[397]:= tmp = Range[15];
tmp[[7]] = Sequence @@ Range[4];
tmp[[7]] = Sequence @@ Range[3];

tmp[[7]] = Sequence @@ Range[2];
tmp

Out[401]= {1, 2, 3, 4, 5, 6, 1, 2, 8, 9, 10, 11, 12, 13, 14, 15}

As you can see, only the last range sticks.

A new hypothesis would be to assume that Mathematica stores lists as a
table of pointers to the list members and that a Sequence not causes
the list to get extra pointers but that the Sequence is still
invisible lurking there with a single pointer pointing to it. Copying
the array may flatten out this structure, so that every member now
gets his own pointer:

In[402]:= tmp = Range[15];
tmp[[7]] = Sequence @@ Range[2]; tmp = tmp;
tmp[[7]] = Sequence @@ Range[2]; tmp = tmp;
tmp[[7]] = Sequence @@ Range[2]; tmp = tmp;
tmp

Out[406]= {1, 2, 3, 4, 5, 6, 1, 2, 2, 2, 8, 9, 10, 11, 12, 13, 14, 15}

This seems to confirm the hypothesis.

The problem seems to be in Set, as Part works OK:
In[476]:= tmp = Range[15];
tmp[[7]] = Sequence @@ Range[2]; {tmp[[7]], tmp[[8]], tmp[[9]]}
tmp[[8]] = Sequence @@ Range[2]; {tmp[[7]], tmp[[8]], tmp[[9]]}
tmp[[9]] = Sequence @@ Range[2]; {tmp[[7]], tmp[[8]], tmp[[9]]}
tmp

Out[477]= {1, 2, 8}

Out[478]= {1, 2, 1}

Out[479]= {1, 2, 1}

Out[480]= {1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 1, 2, 10, 11, 12, 13, 14, 15}

Could you report this to sup...@wolfram.com?

Cheers -- Sjoerd

### mkr

Nov 25, 2009, 11:00:29â€¯PM11/25/09
to
On Nov 25, 3:22 am, "Sjoerd C. de Vries" <sjoerd.c.devr...@gmail.com>
wrote:
> Could you report this to supp...@wolfram.com?

>
> Cheers -- Sjoerd
>
> On Nov 25, 9:31 am, mkr <mileskra...@gmail.com> wrote:
>
>
>
> > I am puzzled by the following behavior:
>
> > tmp = Range[15]
> > tmp[[7]] = Sequence @@ Range[2];
> > tmp[[7]] = Sequence @@ Range[2];
> > tmp[[7]] = Sequence @@ Range[2];
> > tmp
>
> > yields
>
> > {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
> > {1, 2, 3, 4, 5, 6, 1, 2, 8, 9, 10, 11, 12, 13, 14, 15}
>
> > I would have expected the repeated assignment to have a repeated
> > effect, thus obtaining
>
> > {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
> > {1, 2, 3, 4, 5, 6, 1, 2, 2, 2, 8, 9, 10, 11, 12, 13, 14, 15}
>
> > Where/why am I wrong?- Hide quoted text -
>
> - Show quoted text -

Thanks for the reply. I have submitted this to WRI tech support as a
possible bug, including reference to your much more thorough analysis
here.

### dh

Nov 25, 2009, 11:01:47â€¯PM11/25/09
to

mkr wrote:

>

> tmp = Range[15]

> tmp

>

> yields

>

>

> effect, thus obtaining

>

>

> Where/why am I wrong?

>

Hi,

I asked the same question some time ago.

Set(=) has the attribute SequenceHold and does NOT evaluate Sequence.

What is assigne to tmp[[7]] is simply Sequence[1,2]. You can convince

yourselfe by: ??tmp

Only when you e.g. display tmp, Sequence will be evaluated.

Daniel

### Bob Hanlon

Nov 25, 2009, 11:01:58â€¯PM11/25/09
to

As stated in the documentation for sequence: assignment and replacement functions have attribute SequenceHold

Attributes[Set]

{HoldFirst,Protected,SequenceHold}

tmp = Range[15]
tmp[[7]] = Sequence @@ Range[2];
tmp[[7]] = Sequence @@ Range[2];
tmp[[7]] = Sequence @@ Range[2];
tmp

{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}

{1,2,3,4,5,6,1,2,8,9,10,11,12,13,14,15}

tmp = Range[15]
tmp[[7]] = Sequence @@ Range[2];

tmp = tmp;

tmp[[7]] = Sequence @@ Range[2];

tmp = tmp;

tmp[[7]] = Sequence @@ Range[2];
tmp

{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}

{1,2,3,4,5,6,1,2,2,2,8,9,10,11,12,13,14,15}

Bob Hanlon

---- mkr <miles...@gmail.com> wrote:

=============

### Sjoerd C. de Vries

Nov 27, 2009, 6:43:44â€¯AM11/27/09
to
I'd say that this is not a wise design decision. IMHO, a statement
like tmp=tmp should have no effect on tmp, whereas with this
SequenceHold situation it has.

Cheers -- Sjoerd

On Nov 26, 6:01 am, Bob Hanlon <hanl...@cox.net> wrote:
> As stated in the documentation for sequence: assignment and replacement f=

unctions have attribute SequenceHold
>
> Attributes[Set]
>
> {HoldFirst,Protected,SequenceHold}
>
> tmp = Range[15]
> tmp[[7]] = Sequence @@ Range[2];
> tmp[[7]] = Sequence @@ Range[2];
> tmp[[7]] = Sequence @@ Range[2];
> tmp
>
> {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
>
> {1,2,3,4,5,6,1,2,8,9,10,11,12,13,14,15}
>
> tmp = Range[15]
> tmp[[7]] = Sequence @@ Range[2];
> tmp = tmp;
> tmp[[7]] = Sequence @@ Range[2];
> tmp = tmp;
> tmp[[7]] = Sequence @@ Range[2];
> tmp
>
> {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
>
> {1,2,3,4,5,6,1,2,2,2,8,9,10,11,12,13,14,15}
>
> Bob Hanlon
>

### da...@wolfram.com

Nov 30, 2009, 6:12:34â€¯AM11/30/09
to
> I'd say that this is not a wise design decision. IMHO, a statement
> like tmp=tmp should have no effect on tmp, whereas with this
> SequenceHold situation it has.
>
> Cheers -- Sjoerd

Perhaps so. I view it, paraphrasing Churchill, as the worst possible
design, except for all the rest.

In the alternative scenario, Sequence[...] things would (I guess) cause
immediate evaluation of the left hand side. This has some bad consequences
and maybe also raises a few questions.

(1) It changes assignment semantics.
(2) It means that deeply nested expressions cannot readily be built
because complexity of adding a level becomes worse (maybe this can largely
be short-circuited, I'm not sure).

Questions:

(1) What is the expected/intended behavior of

In[87]:= ss = {a, b, c, d}; Do[ss[[j]] = Sequence[j, j + 1], {j, Length[ss]}]
?

ss2 = Table[Unevaluated[Sequence[i, i^2]], {i, 4}]
?

Maybe that second one is obvious, and no different from current behavior.

All the same, I think it would not be good to have a semantics wherein the
assignment in the Do loop causes evaluation of the lhs in each iteration.

Daniel Lichtblau
Wolfram Research

> On Nov 26, 6:01 am, Bob Hanlon <hanl...@cox.net> wrote:

>> As stated in the documentation for sequence: assignment and replacement

>> f=

> unctions have attribute SequenceHold
>>
>> Attributes[Set]
>>
>> {HoldFirst,Protected,SequenceHold}
>>
>> tmp = Range[15]
>> tmp[[7]] = Sequence @@ Range[2];
>> tmp[[7]] = Sequence @@ Range[2];
>> tmp[[7]] = Sequence @@ Range[2];
>> tmp
>>
>> {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
>>
>> {1,2,3,4,5,6,1,2,8,9,10,11,12,13,14,15}
>>
>> tmp = Range[15]
>> tmp[[7]] = Sequence @@ Range[2];
>> tmp = tmp;
>> tmp[[7]] = Sequence @@ Range[2];
>> tmp = tmp;
>> tmp[[7]] = Sequence @@ Range[2];
>> tmp
>>
>> {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
>>
>> {1,2,3,4,5,6,1,2,2,2,8,9,10,11,12,13,14,15}
>>
>> Bob Hanlon
>>

### Sjoerd C. de Vries

Dec 1, 2009, 4:13:18â€¯AM12/1/09
to
Hi Daniel,

Actually, in all my years with Mathematica I haven't had a single
occasion in which Sequence would used in this way, so perhaps the
whole discussion is moot.

> (1) What is the expected/intended behavior of
>
> In[87]:= ss = {a, b, c, d}; Do[ss[[j]] = Sequence[j, j + 1], {j,
> Length[ss]}]

Well, I know now that it is supposed to be {1, 2, 2, 3, 3, 4, 4, 5},
but my intuition would say {1, 2, 3, 4, 5, b, c, d}.

Look at this sequence (sic) of instructions (and execute it as a
whole):

s = {1, 2, 3}
s[[1]] = Sequence[4, 5]
s[[1]]
s[[2]]
s[[2]] = DifferentValueForIndex2
s[[2]]
s

The first time you ask for the contents of s[[2]] it is 5 (and this is
the only 5 you put in the list), then you assign something else to s
[[2]], so any average programmer would think the 5 is gone out of the
list now. But, surprise, there it still is... big magic

I'd say if you can check and use the value at index 2 for
calculations, you should be able to set the value at index 2, but you
can't in this case.

I wonder how many of your colleagues, when shown the subsequence of

s[[2]]
s[[2]] = DifferentValueForIndex2
s[[2]]

without showing them the first part, will be utterly amazed, and won't
know what's causing this.

Cheers -- Sjoerd

On Nov 30, 1:12 pm, d...@wolfram.com wrote:
> > I'd say that this is not a wise design decision. IMHO, a statement
> > like tmp=tmp should have no effect on tmp, whereas with this
> > SequenceHold situation it has.
>
> > Cheers -- Sjoerd
>
> Perhaps so. I view it, paraphrasing Churchill, as the worst possible
> design, except for all the rest.
>
> In the alternative scenario, Sequence[...] things would (I guess) cause

> immediate evaluation of the left hand side. This has some bad consequence=

s
> and maybe also raises a few questions.
>
>
> (1) It changes assignment semantics.
> (2) It means that deeply nested expressions cannot readily be built

> because complexity of adding a level becomes worse (maybe this can largel=

y
> be short-circuited, I'm not sure).
>
> Questions:
>
> (1) What is the expected/intended behavior of
>

> In[87]:= ss = {a, b, c, d}; Do[ss[[j]] = Sequence[j, j + 1], {j, Le=

ngth[ss]}]
> ?
>
> ss2 = Table[Unevaluated[Sequence[i, i^2]], {i, 4}]
> ?
>
> Maybe that second one is obvious, and no different from current behavior.
>

> All the same, I think it would not be good to have a semantics wherein th=

e
> assignment in the Do loop causes evaluation of the lhs in each iteration.
>
> Daniel Lichtblau
> Wolfram Research
>
> > On Nov 26, 6:01 am, Bob Hanlon <hanl...@cox.net> wrote:

> >> As stated in the documentation for sequence: assignment and replacemen=

0 new messages