1

I'm having a very simple but nasty problem with mathematica:

I need/want to enter symbols using a leading zero

\[alpha]^0123

or even simpler just

mysymbol[0123]

which I then transform to my internal representation

(using the Notation package and IntegerDigits[] or Characters[])

==> myrep[{0,1,2,3}]

everything works fine for input without a leading 0.

BUT WHATEVER I TRY (Unevaluated[] or Hold[]), mathematica (it's overarching evaluator?) will transform the Integer

0123 => 123

so the 0 will be missing from my list

Of course, I could avoid the problem by requiring quotes or commas for the input, but that's rather unpretty!

ANY IDEAS?

nuu
  • 584
  • 4
  • 12
  • NoEscape, the answer I gave you was wrong. There *is* a way to do what you desire. Please see my rewritten answer. – Mr.Wizard Sep 30 '12 at 09:28
  • wow, thanks. my threat of downvoting seems to have worked pretty well ;o) – nuu Sep 30 '12 at 09:45
  • The carrot usually works better than the stick. My original answer was *not* ignoring what you stated in the question, it was merely trying to explain what I (incorrectly) thought were the limitations of the system. (Go ahead and delete the comments as they no longer make sense.) – Mr.Wizard Sep 30 '12 at 09:47
  • It it just a matter of style. I used the more restricted-domain function because that is the input I anticipated (and in fact filter for with `DigitCharacter ..`). `FromDigits` is also faster than `ToExpression` in this application. – Mr.Wizard Sep 30 '12 at 10:16

1 Answers1

3

I answered this question in a definitive tone, but I was wrong. Expressions such as 0123, 16^^8b and 1*^6 are not converted during parsing as I had incorrectly recalled. For this reason we would not need to fall back to the heavy duty and unwieldy CellEvaluationFunction but can instead use the much more user-friendly $PreRead.

This is still a little dangerous as once the definition to $PreRead is made it changes all input, even attempts to change $PreRead. For example, if we were to set $PreRead = Null & it would become impossible to enter additional commands until the Kernel was restarted.

To enact your desired behavior as I understand it we may use:

mysymbol[s_String] := myrep[FromDigits /@ Characters@s]

$PreRead = # /. {RowBox[{"mysymbol", "[", digits_String, "]"}] | 
                 RowBox[{digits_String, "//", "mysymbol"}] |
                 RowBox[{"mysymbol", "@", digits_String}] /; 
                 StringMatchQ[digits, DigitCharacter ..] :> 
                 ToBoxes[ mysymbol@digits ]} &;

Testing:

mysymbol[0123]
myrep[{0, 1, 2, 3}]
Community
  • 1
  • 1
Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
  • which is the best practice for setting $PreRead if I'm building a package - maybe it has aready been set by another package? – nuu Sep 30 '12 at 10:18
  • the FromDigits /@ in your first line works, but is misleading. It looks like we were trying to make an int again from the digits, which we are NOT. Why not use ToExpression /@ Characters@s – nuu Sep 30 '12 at 10:18
  • @NoEscape As I said, "`$PreRead` is still a little dangerous" -- You are quite right that it may already be in use, and that causes problems if you are trying to include something like this in a package. I suggest you save the existing value of `$PreRead` (if defined) to another global variable, e.g. `$oldPreRead`, and apply it afterward. Example: `$oldPreRead = If[ValueQ@$PreRead, $PreRead, Identity]; $PreRead = ((# /. { (* replacements *) }) // $oldPreRead) &;` – Mr.Wizard Sep 30 '12 at 10:33