# How to force the FrontEnd to add (Plus)

You need to set up the LinkSnooper to follow the steps from this question:

So, if you have it set for a notebook or \$FrontEndSession you can check that a Button's action in:

DynamicModule[{x}, {Button["+", FEPrivateSet[x, 1]], Dynamic[x]}]


nicely changes x to 1 without calling the Kernel. However, a slightly complicated example needs Kernel's help:

DynamicModule[{x}, {Button["+", FEPrivateSet[x, 1 + 1]], Dynamic[x]}]


There is no Plus in FEPrivate context. But we know that the FrontEnd knows how to add:

DynamicModule[{x},
{Slider[Dynamic[x], {1, 20}], Style[1, FontSize -> Dynamic[x + 12]]}
]


The question is, how to force it to add, in the first/second example, without calling the Kernel.

Here is a hilarious trick (not useful in general):

DynamicModule[{x}, {Slider[Dynamic[x], {1, 20}], Dynamic[11 + x]}]

DynamicModule[{x},
{Slider[Dynamic[x], {1, 20}],
Style[Dynamic@CurrentValue[FontSize], FontSize -> Dynamic[11 + x]]
}
]


• not sure but I think that what the second kernel that always is started with newer versions might be used for? Oct 4 '16 at 15:59
• @AlbertRetey my point is rather how to write 1+1 so that FE adds it by itself instead of sending to the main Kernel. And I don't care how it will be done :)
– Kuba
Oct 4 '16 at 18:40
• actually my hopes that this will be answered rest entirely on you Oct 4 '16 at 23:37
• @AlbertRetey and others, the state of art is you can't do that. FE's kernel is limited and addition in mathematica is a complex task as it supports not only machine precision but exact numbers etc, not to mention arbitrary expressions. FE can't handle that so this path is closed for users. More or less what JF told me year ago or so, forgot to add this comment.
– Kuba
Aug 10 '17 at 10:50

This is not the most serious answer, but you could use the following. Its most practical use is if you want a simple counter or something like that. It works with binary representations of numbers, where True means 1 and False means 0. It is based on the concept of a half adder. Don't be fooled by the quasi informative comments that may give the impression that the code is understandable, in the end the code has become quite write-only.

nn = 2;

(*first argument (input) is the carry*)
(*output[[1]] is the value *)
(*output[[2,1]] is the carry *)
(*output[[2,2;;]] is the rest of the numbers that have to be added *)
Function @@
Function[Null, Hold@{Xor[#, #2], {# && #2, ##3, False}}, HoldAll] @@
Part @@@ Hold @@ ({Slot @@ {1}, #} & /@ Range[nn + 1]);

cyclerReducer =
List @@@
Function@Evaluate@
Join[
Hold[#[[1, 2]]],
Apply[Part,
Hold@Evaluate@
Append[{Slot @@ {1}, 2, #} & /@ Range[2, nn + 1], {#, 1, 1}]
, {2}]
];

argListHeld =
List @@@ Hold@Evaluate@
Append[
List @@@ Hold@Evaluate@
Prepend[
Part @@@
Hold @@
({Slot @@ {1}, # } & /@ Range[nn]),
True],
ConstantArray[False, nn + 1]
];

plusOne =
Part @@@ Function@Evaluate@
Append[Nest[Unevaluated@halfAddStep /@ # &, argListHeld, nn + 1],
2];

plusOneCode =
plusOne //.
Join[
Join @@
OwnValues /@
,
{And -> FEPrivateAnd, Xor[x_, y_] :>  SameQ[SameQ[x, y], False]}
];


Here are some tests to see how plusOne can be used

testFu =
FromDigits[Reverse@#, 2] &@
Boole@Most@
Nest[plusOne, OddQ /@ Reverse@IntegerDigits[#, 2, nn], #2] &;
plusOne[ConstantArray[False, nn]]
Nest[plusOne, ConstantArray[False, nn], 2^nn]

{True,False,False}
{False,False,True}


We can use the function like plus, but we will have to add 1 a lot of times.

testFu[#, #2] == Mod[# + #2, 2^nn] &[324232, 3445]

True


Using the following, we see that it can work completely in the Front End. We use plusOneCode instead of plusOne, because a few modifications were needed to make it work Front-End-only. Click the square a few times to toggle the colour. Uncomment the comment to see that we are counting using x.

ReleaseHold[
ReplaceAll[#,
Join[OwnValues[
plusOneCode], {startCount -> ConstantArray[False, nn + 1],
targetCount -> Append[ConstantArray[False, nn], True]}]] &@
Hold@
DynamicModule[{x, y = False},
x = startCount;
Column@
{
Graphics@
{
DynamicBox[If[y, RGBColor[1, 0, 1], RGBColor[0, 1, 0]]],
EventHandler[
Rectangle[{0, 0}], "MouseDown" :> (

FEPrivateSet[y,
SameQ[FEPrivateSet[x, plusOneCode[x]], targetCount]]
)

]
}
(*,
Dynamic[Column@x]*)
}
]
]


The following shows that doings things in the kernel is about 20x faster

feTimingFunc = (Function @@ Nest[plusOneCode /@ # &, Hold[#], 500]);
kerTimingFunc = (Function @@ Nest[plusOne /@ # &, Hold[#], 500]);
kerRes = kerTimingFunc[ConstantArray[False, nn + 1]]; //
AbsoluteTiming // First
ReleaseHold[
Hold[
feRes = FEEvaluate@feTimingFunc[input]
] /.
Append[OwnValues[feTimingFunc],
input -> ConstantArray[False, nn + 1]]
] // AbsoluteTiming // First

0.013697
0.210329


Somehow something breaks down if we nest the function more than 500 times, probably the front ends recursion limit is reached. Timings are quite acceptable compared to other delays when using Dynamic`, in my opinion.