1
$\begingroup$

In my code I have

With[
 {
  rowCells=(genCells[#]&/@genSpecs[#])&/@clueRows,
  colCells=(genCells[#]&/@genSpecs[#])&/@clueCols
 },
 While[Not@isDone@Flatten@constraintTable,
    constraintTable=(Thread[f[rowCells,constraintTable]]/.f-> constraintStrip);
    constraintTable=(Thread[f[colCells,constraintTable\[Transpose]]]
                     /.f-> constraintStrip)\[Transpose];
 ]
]

but when I attempt to replace the substitutions for f with

With[
  {
   rowCells=(genCells[#]&/@genSpecs[#])&/@clueRows,
   colCells=(genCells[#]&/@genSpecs[#])&/@clueCols
  },
  While[Not@isDone@Flatten@constraintTable,
    constraintTable=(Thread[constraintStrip[rowCells,constraintTable]]);
    constraintTable=(Thread[constraintStrip[colCells,constraintTable\[Transpose]]]
                       /.f-> constraintStrip)\[Transpose];
  ]
]

I get

Transpose::nmtx: The first two levels of {Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0],Transpose[0]} cannot be transposed. >>
Transpose::nmtx: "The first two levels of {Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[],Transpose[]} cannot be transposed. \!\(\*ButtonBox[\">>\",

Why do I need to substitute in this way? How can avoid having to do so?


I have a similar issue with

showTable[t_]:=
Grid[
  Join[
    Join[
      ConstantArray["",{9,9},(Style[#,Bold]&/@PadLeft[#,9,""]&/@clueCols)]\[Transpose],
      (Thread[f[(Style[#,Bold]&/@PadLeft[#,9,""]&/@clueRows),
                (t/.cellGraphics)
               ]
    ]/.f->Join)
   ], 
   gridSpecs
];

where a substitution is also required in Thread to avoid errors.

$\endgroup$
17
  • 3
    $\begingroup$ Thread evaluates its argument before threading, so perhaps the problem comes from evaluating constraintStrip[rowCells,constraintTable]. $\endgroup$ Dec 14, 2015 at 21:20
  • $\begingroup$ @SimonWoods: How can it thread over something if it evaluates the whole thing first? $\endgroup$
    – orome
    Dec 14, 2015 at 21:23
  • $\begingroup$ For many things that's no problem: Thread[{a,b}->{1,2} yields {a->1,b->2}, which is quite useful. $\endgroup$ Dec 14, 2015 at 21:26
  • 2
    $\begingroup$ If that is the source of the problem, the question is essentially a duplicate of this one $\endgroup$ Dec 14, 2015 at 21:27
  • 1
    $\begingroup$ It's not messed up, {1,2,3}=={1,2,3} evaluates to True - what do you think the result of Thread[True] should be? $\endgroup$ Dec 14, 2015 at 22:06

1 Answer 1

2
$\begingroup$

If you want to avoid the substitution, it might be more "elegant" to use MapThread:

MapThread[Join, {colCells, constraintTable\[Transpose]}]

This works like Thread, but Join directly operates on the right arguments.

$\endgroup$
5
  • $\begingroup$ Yes, MapThread gives the expected behavior, but why have Thread behave this way at all? $\endgroup$
    – orome
    Dec 14, 2015 at 23:07
  • $\begingroup$ @raxacoricofallapatorius Beacause Thread has not attributes like HoldAll and the like, so it first evaluates its arguments, as you can see evaluating Thread[(Print["f"]; f)[(Print["a"]; {a1, a2, a3}), (Print["b"]; {b1, b2, b3})]]. This prints "f", "a" and "b" and then threads f over the two list. $\endgroup$
    – user8074
    Dec 14, 2015 at 23:15
  • $\begingroup$ But why have Thread do that? Why have Thread designed to not thread in some cases. $\endgroup$
    – orome
    Dec 14, 2015 at 23:16
  • $\begingroup$ @raxacoricofallapatorius, the error comes from the effect of Join, not from from the behavior of Thread: when Join evaluates its arguments (before Thread acts, since the evaluations start from the leaves of the expression tree) it produces a single list, with the wrong shape for Thread. The reason why Thread is not holding it's argument should be explained by MMA designers. $\endgroup$
    – user8074
    Dec 14, 2015 at 23:25
  • $\begingroup$ I don't think Join comes into play in the first case though, where f is constraintStrip. $\endgroup$
    – orome
    Dec 14, 2015 at 23:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.