4
$\begingroup$

I am implementing pseudocode in Mathematica for a class I'm teaching. I would like to copy the textbook syntax which is IF ... THEN ... ELSE ... ENDIF. My results are not very satisfactory and my question is whether there is a way of overcoming the problems I've met.

I have used the Notation package as follows:

Mathematica graphics

now this is fine as far as it goes, but my first problem is that the precedence structure it creates means that compound arguments x, y and z have to be enclosed in brackets or the "keywords" are treated as multipliers:

IF (3 < 5) THEN a ELSE b ENDIF (* parses ok: returns a *)
IF  3 < 5  THEN a ELSE b ENDIF (* does not parse ok *)

output: Mathematica graphics

a related issue is that I cannot split expressions over multiple lines without introducing bracketed expressions and putting the newlines within the brackets:

complicatedExpressionInvolvingReturns = 99998;
anotherComplicatedExpressionInvolvingReturns = Total;
IF (
  complicatedExpressionInvolvingReturns
   >= 99999
  ) THEN (
  anotherComplicatedExpressionInvolvingReturns[
   {y1, y2, y3, y4}]
  ) ELSE (

  anotherComplicatedExpressionInvolvingReturns[
   {y4, y3, y2, y1}]
  ) ENDIF

my second issue is that I would like If[a,b,c] to print as IF a THEN b ELSE c ENDIF but I have not found a way of using Notation to do this.

Is there a better way of doing this, perhaps without using the Notation package?

$\endgroup$
  • $\begingroup$ I don't know what I changed, but now If[a,b,c] is now printed in the form I prefer $\endgroup$ – fairflow Sep 12 '16 at 11:08
  • $\begingroup$ Precedence of operators is hard coded and I don't know any way to hack it. Front End is creating box expressions, according to built-in precedence, while code is typed. You can "intercept" boxes, before they are converted to expression, using $PreRead, but writing robust parser that would change built-in precedence, by untangling all possible box structures, seems to be an enormous work. $\endgroup$ – jkuczm Sep 19 '16 at 13:25
3
$\begingroup$

Inspired by my answer to Seeking more verbose syntax, e.g. "Then" -> ",", I thought I would try a similar approach for this question. So, define the following aliases:

CurrentValue[EvaluationNotebook[], {InputAutoReplacements, "if"}] = RowBox[{
    TemplateBox[
        {},
        "if", 
        DisplayFunction->(StyleBox["IF", ShowAutoStyles->False, FontColor->GrayLevel[.5]]&),
        InterpretationFunction->("If"&)
    ],
    StyleBox["[",ShowContents->False],
    StyleBox["\[NegativeMediumSpace]", ShowContents->True]  
}];
CurrentValue[EvaluationNotebook[], {InputAutoReplacements, "then"}] = TemplateBox[
    {},
    "then",
    DisplayFunction->(StyleBox["THEN", ShowAutoStyles->False, FontColor->GrayLevel[.5]]&),
    InterpretationFunction->(","&),
    SyntaxForm->","
];
CurrentValue[EvaluationNotebook[], {InputAutoReplacements, "else"}] = TemplateBox[
    {},
    "else",
    DisplayFunction->(StyleBox["ELSE", ShowAutoStyles->False, FontColor->GrayLevel[.5]]&),
    InterpretationFunction->(","&),
    SyntaxForm->","
];
CurrentValue[EvaluationNotebook[], {InputAutoReplacements, "endif"}] = TemplateBox[
    {},
    "endif",
    DisplayFunction->(StyleBox["ENDIF", ShowAutoStyles->False, FontColor->GrayLevel[.5]]&),
    InterpretationFunction->("]"&),
    SyntaxForm->"]"
];

I fixed some issues with my initial answer, and I changed to input auto replacements a la Chip Hurt's answer to the linked question. It should be much more robust. An animation showing it in action:

enter image description here

$\endgroup$
  • $\begingroup$ nice. It should be possible to combine with a Notation-style output format that matches the input. $\endgroup$ – fairflow Jul 4 at 18:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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