One moment I decided to assign symbolic names to all special spaces since they all look the same when put literally in FrontEnd editor, more or less like "" or " ".
I wrote the following macro:
Block[{Set}, Set @@@
( MapAt[
Composition[Symbol
, StringReplace[#, "[" | "]" | "\"" | "\\" ] -> ""]& ]
, #, {1}] & /@
Select[
{ToString@FullForm@#, #} & /@
FromCharacterCode /@ (-1 + Range[2^16])
, StringMatchQ[First@#, ___ ~~ "Space]\""] &] ) ];
that checks all Unicode chars recognised by Mathematica as “smth-Space”, fetches symbol names and performs the assignments. After macro expansion I expect to get
Block[{Set}, Set @@@
{ { NonBreakingSpace, " " }
, { ThickSpace, " " }
, { ThinSpace, " " }
, (…rest) }]
However, while the expression in round brackets does evaluate to correct table of symbols and various spaces if evaluated independently, and Set@@@ on it works perfectly well, the whole macro Block[{Set}, …] starts throwing lots of errors, from $RecursionLimit and ToExpression. (Being a bit too hasty, I put it into pre-loaded packages — naturally, it made Kernel crash every time I attempted to start it.)
That said, Block[{set}, set@@@(…) /. set -> Set] works OK, but the question remains: what causes the problem in the original macro? This is not the first time I make assignment with Block[{Set}, Set@@@table];, and I would like to keep doing it further. The issue is surprising.
The only explanation I see is that Blocking Set somehow interferes with evaluating the expression in round brackets (the one meant to evaluate to the table). But this behaviour is quite unexpectable unless I miss something obvious, and there also does not seem to be a way to trace the evaluation.
1) Is there a way to Trace the evaluation?
2) What really causes the problem? (In case it is possible to find out at all without cracking the kernel.)
Setis a really bad idea, unless you want to block everything else insideBlockas well, to make the code completely inert. You never know what system functionality will be affected, but with a function as fundamental asSet, you can be sure that some will. This kind of code / changes are enough for me to not be willing to spend any time looking deeper, don't know about the others. – Leonid Shifrin Apr 07 '14 at 17:44Set, you delay assignments to some variables / L-value-expressions. If those expressions are passed to some functions, those functions are not getting what they would expect to get at that stage. In more traditional languages, calling an undefined function (Sethere) would ... – Leonid Shifrin Apr 07 '14 at 21:45Block-ing Set you change the evaluation sequence for internal functions (which useSet) in a way they weren't designed to handle. In most languages, you can't even do anything as fundamental as changing the semantics of core operations such as assignments via dynamic scoping, for a part of execution stack rather than a part of the source code. This is a fairly disruptive / intrusive change, it is even much worse than things like AOP. – Leonid Shifrin Apr 07 '14 at 21:50Module,Block, or evenCompoundExpression, does that - because it makes no sense to use these functions if you don't have side effects in that code. And of course, a lot of internal functions use those constructs, because Mathematica is largely written in itself. If you had a picture of Mathematica being pure stateless rewrite system, that's a wrong picture. – Leonid Shifrin Apr 07 '14 at 21:54With,Function, or replacement rules - as well as tools of evaluation control (Holdand friends). – Leonid Shifrin Apr 07 '14 at 22:13Setcan be thought of as a constructor of global rules (which it is). ByBlock-ing it, you change the sequence in which global rules are constructed, which is equivalent to changing the order in which they are applied – Leonid Shifrin Apr 07 '14 at 22:17Setis very infrequent and thought of as a last resort. It is almost just as bad to do that internally as when done by the end user, because any two such modifications done independently can conflict in hard to predict ways, and because it hinders the generality of the language. So, I wouldn't get disappointed just yet - a lot of thought has been put into the design of every (core) feature, and, at least in my view, there are very few inconsistent places. – Leonid Shifrin Apr 07 '14 at 22:30