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$ – J. M.'s ennui Nov 26 '15 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$ – J. M.'s ennui Nov 26 '15 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$ – Daniel Lichtblau Nov 26 '15 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$ – Daniel Lichtblau Nov 26 '15 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$ – Daniel Lichtblau Nov 26 '15 at 18:25
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$ – Dustin Darcy Nov 26 '15 at 10:55
  • $\begingroup$ @DustinDarcy See my edit. $\endgroup$ – xzczd Nov 26 '15 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$ – Dustin Darcy Nov 27 '15 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 '15 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 '15 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 '15 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$ – Dustin Darcy Nov 28 '15 at 4:39

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.