I agree that a literal 2 is probably bad to use in "Math.max(2, e)", but it is also probably as bad in "partial(Math.max, 2)", and even worse is the "Two" embedded in the function name in "function atLeastTwo(someNumber) {...}".
I decided to let that ride rather than change it to something like MIN_SAFE_VALUE like it should be in real code.
So supposed that is fixed, and we have MIN_SAFE_VALUE defined somewhere, so that we don't have to worry about typos (much...if we have a MIN_SAVE_VALUE too that could be trouble).
Also suppose that MIN_SAFE_VALUE is used instead of 2 in "partial(Math.max, ...)". Alternatively, if that is the only place that actually uses MIN_SAFE_VALUE, with everyone else using it via the partial function, then I suppose it would be OK to use the 2 literally there, and name the result of partial with a name that says it it ensures the minimum safe value.
Same for the "function atLeastTwo" approach. Give it a good name, and get rid of the magic number in the definition, unless that is the only place that uses MIN_SAFE_VALUE directly and then maybe it is OK for that to be where the literal 2 appears and not have a MIN_SAFE_VALUE constant defined. (I'd still go for a defined constant, because it and any other such magic numbers can be defined in one place making it easier for people who need to tune things later).
Now I can see why the "partial" approach and the regular function approach might win over inline "Math.max(MIN_SAFE_VALUE, ...)", because they both make it easier to change how the safety constraint is enforced.
For example let's say this code is part of the control system for a power plant. The engineers revise the rules to allow going 10% under the normal minimum safe value when the plant is operating more than 20% below peak capacity.
With the regular function approach we only have to change that one function so that it checks the operating level and adjusts the threshold it checks against accordingly. With the partial approach we could probably also do something like that (although maybe we'd need a helper function since we would no longer be applying partial to an already existing function.
With the "Math.max(MIN_SAFE_VALUE, ...)" everywhere approach we'd have to change all those places. (Except if we were in C or C++, and MIN_SAFE_VALUE was a simple #define. Then maybe we could change that from "#define MIN_SAFE_VALUE 2" to "#define MIN_SAFE_VALUE current_safe_value()" and write a current_safe_value() function. That still limits is to only handling safe value rules that involve a >= comparison of the value with a threshold, so is still not as flexible as the normal function approach.
But note that this advantage comes from pushing the algorithm of the safety check down to underlying functions, instead of exposing it at the point of use. Using Math.max at the place where you are actually checking the value and using the corrected value exposes at that point that the algorithm is to compare to something and pick the larger of the two.
For me the article just didn't explain why pushing the algorithms lower in point-free style is better than doing that in normal function style, and didn't seem to have any other compelling thing point-free does. This is probably a topic that needs more than the 148 words in the article's "Why Does It Matter?" section.
Some of the comments here using Haskell look more interesting, but I've only looked a little at Haskell. They all quickly hit my limit--the before and after Haskell examples look like something compelling is happening but I just am not yet able to see what that is.