MathGroup Archive 2013

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Using Defer on Dynamic Expressions?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg129748] Re: Using Defer on Dynamic Expressions?
  • From: John Fultz <jfultz at wolfram.com>
  • Date: Sun, 10 Feb 2013 03:24:54 -0500 (EST)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com
  • Delivered-to: l-mathgroup@wolfram.com
  • Delivered-to: mathgroup-newout@smc.vnet.net
  • Delivered-to: mathgroup-newsend@smc.vnet.net
  • References: <20130209054250.CD8036929@smc.vnet.net>

As you may know, when you do an evaluation in Mathematica, there are two 
steps for preparing that evaluation to return as an output.

First, the evaluation is actually performed.  Then the evaluation is 
"typeset", which is to say the kernel runs MakeBoxes on the result of 
the evaluation and sends the boxes back to the front end.

There are some functions which don't do anything particularly 
interesting at evaluation time, but do something interesting as a result 
of typesetting.  For example, Grid[] is very boring at evaluation time.  
When you evaluate it, it evaluates its arguments, but the Grid[] itself 
still remains as something of an inert wrapper.  But when you typeset 
it, you suddenly get this new and interesting behavior where you get a 
grid onscreen.  Since CellPrint of ExpressionCell is doing typesetting, 
that's the kind of behavior you're getting.  E.g.,

CellPrint[ExpressionCell[Grid[{{1, 2}, {3, 4}}]]]

What may not be obvious is that things like Dynamic, DynamicModule, and 
Manipulate are *exactly* like Grid in this regard.  The evaluation 
properties of Dynamic and Manipulate vary slightly since they hold their 
arguments.  But otherwise, these are functions which essentially do 
nothing interesting until you typeset them.  And since we know that 
CellPrint of ExpressionCell does typesetting, that explains the behavior 
you're seeing.  So Defer isn't helpful, since all Defer does is prevent 
evaluation, not typesetting.

There's no documented way to do anything different.  Even if you call 
MakeBoxes or ToBoxes by hand, that won't help, as they're also going to 
just typeset the result.  By any documented means, it looks hopeless.  
But Mathematica does know how to do this.  If you use the Cell->Convert 
To->StandardForm menu command on a cell, it doesn't turn all Grids into 
GridBoxes or all Manipulates into live active Manipulates.  So it's 
definitely possible.  Which means, to answer this question, I'm going to 
have to go way off the rails into undocumented (and unsupported) 
territory.

So, the best answer I can give to your question involves calling ToBoxes 
under controlled circumstances.  And the controlled circumstance 
involves setting the following internal variable to True:

BoxForm`$UseTextFormattingWhenEvaluating

This variable is looked at by the internal typesetting system to 
determine whether to format things like Grid and Manipulate textually or 
as GridBoxes and interactive interfaces.  Setting it to True gets the 
typesetting we want.  So let's use that to define a new CellPrint-ing 
function:


SetAttributes[newCellPrint, HoldAll];
newCellPrint[cell_] :=
 CellPrint[
  ExpressionCell[
   Block[{BoxForm`$UseTextFormattingWhenEvaluating = True},
    RawBoxes[MakeBoxes[cell]]], "Input"]]


Notice I'm not using Defer here because MakeBoxes is HoldAll and our new 
function is HoldAll, so Defer is no longer necessary.  But now I've 
locally changed the behavior of our MakeBoxes call by changing 
BoxForm`$UseTextFormattingWhenEvaluating in the Block[] to get the 
behavior your'e looking for.

Although this is undocumented and unsupported, it works from at least v7 
(and probably v6, but I didn't test it) to v9, and I don't anticipate 
any reason why this would change in the foreseeable future.

John Fultz
jfultz at wolfram.com
User Interface Group
Wolfram Research, Inc.



On Feb 8, 2013, at 11:42 PM, W Craig Carter <ccarter at MIT.EDU> wrote:

> Hello Mathgroup,
> I am doing a little notebook programming and am stuck on something:
>
> Note that these two commands differ in their behavior:
>
> CellPrint[
> ExpressionCell[
>  Defer[
>   Table[x, {x, 0, 10, 1}]
>   ],
>  "Input"]
> ]
>
> CellPrint[
> ExpressionCell[
>  Defer[
>   Manipulate[x, {x, 0, 10, 1}]
>   ],
>  "Input"]
> ]
>
> The front end seems to ignore the Defer request when a command would
> have dynamic output.  Is there any way to get the same behavior (i.e.,
> that for Table) as for Manipulate?
>
> Thanks, Craig
>
>
> W Craig Carter
> Professor of Materials Science, MIT




  • Prev by Date: Re: Using a notebook - how to add a caption and ...
  • Next by Date: Re: Mathematica and Lisp
  • Previous by thread: Using Defer on Dynamic Expressions?
  • Next by thread: Re: Undo/Redo