MathGroup Archive 2012

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

Search the Archive

Re: Implicit Times

  • To: mathgroup at smc.vnet.net
  • Subject: [mg128669] Re: Implicit Times
  • From: awnl <awnl at gmx-topmail.de>
  • Date: Thu, 15 Nov 2012 03:58:55 -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: <k7hh3j$nv1$1@smc.vnet.net>

Hi,

> Mathematica assumes Times (*) when two expressions are
> juxtaposed with no explicit intervening binary operator
> (ex., x y is interpreted as x*y).
> I want to change this behavior so it assumes a
> NonCommutativeMultiply (**) instead.
> Is this possible?

It is possible, but I'd hardly recommend to do it, it is probably just 
as dangerous as overwriting important internal symbols like Times. What 
you want to do is interfering with Mathematica at a very deep level so 
be warned to be cautious when playing with these things: errors at that 
level might crash or hang the Kernel, the FrontEnd or even the OS (at 
least a Windows box). AFAIK there are two possible approaches, either 
you can use the hook $PreRead to manipulate the boxes before parsing 
(and $Pre to manipulate the unevaluated input) or use MakeExpression 
which lets you redefine how boxes are converted to expressions. I think 
it is somewhat easier to use $PreRead and $Pre for what you need and 
found MakeExpression even more dangerous than those, so I'll stick with 
$PreRead and $Pre in the following. You should also note that this 
approach might need some changes when you want it to work with InputForm 
strings as e.g. when reading package files. What I'll show will in this 
form only work in the notebook interface.

Even though the mentioned functions let you manipulate the boxes at a 
very early stage of the evaluation process, the conversion of spaces has 
already been done, as you can learn from the documentation 
(tutorial/LowLevelInputAndOutputRules) and verify with this:

$PreRead=Function[Print[#];#];
a*b c**d
$PreRead=.;

Nevertheless, building on David Baileys tricks with interpreting strings 
we can apply the same strategy to manipulate the boxes, but we have to 
take special care to not evaluate too early which makes the following 
somewhat lengthy. The following definitions will basically do what you want:

$PreRead = Function[
   Function[x, MakeBoxes[x, StandardForm], HoldAllComplete] @@ (
     MakeExpression[# /. "*" -> "\[Star]", StandardForm] /.
      Times -> NonCommutativeMultiply
     )];
$Pre = Function[Null, ReleaseHold[HoldComplete[#] /. Star -> Times],
   HoldAllComplete];

a (a b)*(c a)


I'm using "\[Star]" as a temporary substitute for "*" here, which looks 
exactly like "*" in a notebook but has the advantage that it's 
precedence is such that no extra care needs to be taken to keep the 
precedence between ** and * (see tutorial/OperatorInputForms in the 
documentation for information on operator precedence).

If at all I would only switch this on temporarily where needed, so as 
soon as not needed anymore you should evaluate:

$PreRead = .; $Pre = .;

If you really want to use such an approach, I'd recommend to define 
helper functions as e.g.:

beginncm[] := (
    $PreRead = Function[
      Function[x, MakeBoxes[x, StandardForm], HoldAllComplete] @@ (
        MakeExpression[# /. "*" -> "\[Star]", StandardForm] /.
         Times -> NonCommutativeMultiply
        )];
    $Pre =
     Function[Null, ReleaseHold[HoldComplete[#] /. Star -> Times],
      HoldAllComplete];
    );
endncm[] := ($PreRead =.; $Pre =.;);

so that you can temporarily switch on the desired behavior without too 
much risk of breaking other things:

beginncm[]
expr = a (a b)*(c a);
endncm[]

you will find that this approach has some subtle problems, but it 
probably is good enough to define expressions with your prefered syntax. 
One of the problems I observed was that e.g. wrappers like FullForm 
don't work as expected. The reason for tis is that 
MakeBoxes[MakeExpression[#]]& isn't an exact identity (MakeExpression 
does obviously does strip some of these wrappers). There could of course 
be other side effects that I didn't happen to observe...

hth,

albert




  • Prev by Date: Re: Euclidean distance of all pairwise combinations (redundants)
  • Next by Date: Re: ImageCapture::caminuse: Camera is already in use by
  • Previous by thread: Re: Implicit Times
  • Next by thread: FindFit::eit Error Message in Mathematica