2
$\begingroup$

Below is a simplified scenario of a problem that I'm running into. There are 3 functions each wrapped with BaseForm[] and a default base of 10 is passed to each through the optional f parameter. Each function depends on the function before it.

Add[a_, b_, f_:10] := BaseForm[a + b, f]
MultSum[a_, b_, c_, f_:10] := BaseForm[Add[a, b]*c, f]
ExpMultSum[a_, b_, c_, d_, f_:10] := BaseForm[MultSum[a, b, c]^d, f]

Please be aware the functions above have nothing to do with what I'm trying to accomplish. They only exist to highlight the issue that I am encountering.

I intentionally avoid passing in the f to the earlier functions because the output format isn't parseable by the caller. Add[] works fine, as does MultSum[], but once we get to ExpMultSum[] the Mathematica 9 parser appears to hit some internal limitation and stops evaluating the expression:

Add[2, 2]
4

MultSum[2,2,2]
8

ExpMultSum[2, 2, 2, 2]
8²

My best guess is that there is a nesting limitation? The only solution I can come up with is to move the BaseForm outside the function and wrap each call (ex. BaseForm[Add[2, 2],10]). Is there a known workaround so I can keep the BaseForm internal to the function?

$\endgroup$
16
  • 1
    $\begingroup$ BaseForm[] is only intended for output formatting. Why not do your arithmetic conventionally, and reserve BaseForm[] when you're ready to display output? $\endgroup$ Nov 26, 2015 at 5:55
  • 2
    $\begingroup$ And that worked out well for you, eh? You can set up $PrePrint to have your output be always printed in base $k$ form, for some globally set value of k. $\endgroup$ Nov 26, 2015 at 6:17
  • 2
    $\begingroup$ (1) This is not the result of any internal limitation. It is a consequence of applying operations intended for arithmetic expressions instead to expressions of the form BaseForm[...]. If you do FullForm[...] of the outputs this will become more clear. $\endgroup$ Nov 26, 2015 at 15:25
  • 2
    $\begingroup$ (2) In essence this is an oft-duplicated question, though usually in regards to results wrapped in MatrixForm[]. As in "Why doesn't mat={{1,2},{3,4}}//MatrixForm;RowReduce[mat] work?". Same issue. $\endgroup$ Nov 26, 2015 at 15:28
  • 1
    $\begingroup$ I don't know why BaseForm[expr,10] formats without the "sub_10" part in contrast to other bases. But that's in the formatting handler. The fact is XXXForm wrappers do not go away, so functions that see them in input need to be prepared for handling them. $\endgroup$ Nov 26, 2015 at 18:25

2 Answers 2

5
$\begingroup$

You can define a customized BaseForm:

(* Solution 1 *)    
baseForm[num_, n_] := BaseForm[num //. BaseForm[a_, _] :> a, n]
(* Solution 2, may be dangerous *)
baseForm[num_, n_] := BaseForm[Block[{BaseForm = # &}, num], n]

But personally I think keeping BaseForm out of the function definition is better. If you feel it cumbersome to type BaseForm from time to time, just define a shorter name for it:

b[n_] := BaseForm[#, n] &
5 // b@4

enter image description here


Update:

The following solution should handle Add[1, 2] + Add[3, 4]:

(* Solution 3 *)
Clear@baseForm

baseForm /: (c : Except[SetDelayed | baseForm])[d___, baseForm[a_, b_], e___] := 
  baseForm[c[d, a, e], b]
baseForm /: MakeBoxes[baseForm[a_, b_], fmt_] := ToBoxes@BaseForm[a, b]

Update 2:

(* Solution 4 *)
baseForm[num_, n_] := ($PrePrint = BaseForm[#, n] &; num)

This solution should be the most robust and sufficient for so long.

$\endgroup$
8
  • $\begingroup$ Clever, I like it! Both solutions solve the nesting problem, but performing an operation like: Add[1,2]+Add[3,4] results in 3+7 instead of 10 due to the default value f_:10 in Add[a_, b_, f_:10]. So close! $\endgroup$ Nov 26, 2015 at 10:55
  • $\begingroup$ @DustinDarcy See my edit. $\endgroup$
    – xzczd
    Nov 26, 2015 at 12:54
  • $\begingroup$ That's one crazy transform! It works, but when the situation gets a bit more hairy (ex. Sum[x, {x, 0, Add[1, 2]}]) it generates: Sum::vloc: "The variable {x,0,3} cannot be localized so that it can be assigned to numerical values." I think it's best to write this one off as being more trouble than it's worth. Your answer definitely wins though and is probably as close as we're going to get without a rewrite of how BaseForm[] treats the default case. Thank you for all your effort. $\endgroup$ Nov 27, 2015 at 3:03
  • 1
    $\begingroup$ @DustinDarcy Thanks for accepting. As to the new sample, it seems that baseForm failed to escape from Sum. This may be because Sum has used some unusual rule for summation. (Here is an evidence for the unusualness of Sum.) A quick fix I can think out is to define a customized Sum: sum[f_, {x_, a_, b_}] := Sum[f, {x, #, #2}] &[a, b]. This is probably not the only edge case though 囧. $\endgroup$
    – xzczd
    Nov 27, 2015 at 5:57
  • $\begingroup$ @DustinDarcy Have a look at my update 2, this solution should be quite robust. The only trouble is that $PrePrint won't be automatically cleared but it's not a big deal. When you don't want to see the BaseForm of the output anymore, just $PrePrint=. $\endgroup$
    – xzczd
    Nov 27, 2015 at 7:36
1
$\begingroup$

One solution that works when the value isn't being stored if it's not base-10 is to use a wrapper to conditionally apply the BaseForm.

baseForm[e_,n_]:=If[n==10,e,BaseForm[e,n]]

This fixes the nesting problem because BaseForm[] is only applied in the last call of the execution stack. It is too bad BaseForm[] doesn't do this by default.

$\endgroup$
2
  • $\begingroup$ Oh… so there doesn't exist something like a = Add[2, 2, 3](* line break *) a + a in your notebook? $\endgroup$
    – xzczd
    Nov 28, 2015 at 2:53
  • $\begingroup$ Good observation, most of the BaseForm[expression, _not_ 10] operations output unstored values which are later referenced by the line number or the result rather than variable to point out changes that are happening. That is definitely a limitation of this approach. Time to go back through the notebook to double check what it might have messed up. $\endgroup$ Nov 28, 2015 at 4:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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