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?
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
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.
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
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:
=============
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
>
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.
Bad consequences:
(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]}]
?
(2) What about
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
>>
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.
>
> Bad consequences:
>
> (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]}]
> ?
>
> (2) What about
> 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=