<p><strong>Note 1:</strong> My question is not about the factorial function. It's about &quot;simple math functions&quot; that high-school level pocket calculators can do, but most programming languages cannot do <em><strong>without calling a library</strong></em> (square roots, logarithms, trigonometric functions, factorials, etc.).</p>
<p><strong>Note 2:</strong>  Comments and answers have said things like &quot;by providing a factorial out-of-the-box you'd deprive CS teachers of their favorite recursive-programming example&quot;. While I agree that this joke is clever, it's unlikely that the developers of Java intentionally didn't include a factorial function so that CS teachers could have something to teach, so this isn't the type of answer I'm seeking.</p>
<hr>
<h1>Preamble</h1>
<p>I understand that not all programming languages can be like MATLAB, which <em>by default</em> allow users to write <code>factorial(10)</code> for 10!, <code>sqrt(10)</code> and for <span class="math-container">$\sqrt{10}$</span>. Indeed, MATLAB, Mathematica, Maple, and other similar platforms, take up considerably more hard drive space than most compilers, even when combined with the space taken up by a typical heavy-weight IDE.</p>
<h1>However, even some of the least sophisticated <em>calculators</em> have a button for these simple functions.</h1>
<p>Why would so many languages like Java and C++ (see <a href="https://stackoverflow.com/q/50132863/1271772">this StackOverflow thread if interested</a>) not have a built-in way (i.e. <em><strong>without using a library</strong></em>) to do the basic math that simple calculators can do?</p>

<h1>Related questions based on prior research:</h1>
<ul>
<li><a href="https://langdev.stackexchange.com/q/1765/34">Is there any particular reason to only include 3 out of the 6 trigonometry functions?</a> (but the answers to that do not answer the question here).</li>
<li><a href="https://cseducators.stackexchange.com/q/7398/8966">Why programming languages does not have factorial function?</a> (the answers say that such functions <em><strong>are not used much</strong></em>, that they would be considered &quot;<em><strong>bloat</strong></em>&quot;, and that language designers want to <em><strong>avoid putting a flag in the ground that says &quot;this is how it's done&quot;</strong></em>; however my opinion is that these functions are common enough to be included in pocket calculators which have fewer KB of RAM than a computer, so they are not much &quot;bloat&quot;, and if there's already a flag in the ground for multiplication and exponentiation I don't see why there can't be one for <code>sin()</code> or factorials).</li>
</ul>

<syntax><language-design><compilers><implementation><math>
Why do so many programming languages not have a "built-in" way to do simple math functions?
CC BY-SA 4.0
2023-11-13T19:29:26.040Z
**Comments have been [moved to chat](https://chat.stackexchange.com/rooms/149687/discussion-on-question-by-nike-dattani-why-do-so-many-programming-languages-not); please do not continue the discussion here.** Before posting a comment below this one, please review the [purposes of comments](/help/privileges/comment). Comments that do not request clarification or suggest improvements usually belong as an [answer](/help/how-to-answer), on [meta], or in [chat]. Comments continuing discussion may be removed.
Michael Homer
CC BY-SA 4.0
2023-11-14T11:10:23.540Z
I think this question would be improved by explaining why you think programming languages should have the same features as calculators. Programming languages are not calculators: They are much more precisely specified, and are used for much more general tasks than calculators are.
preferred_anon
CC BY-SA 4.0
2024-09-14T00:49:10.390Z
Logint and square root can be done in nearly any language I know ...
Roddy MacPhee
<blockquote>
<p>most programming languages cannot do <strong><em>without calling a library</em></strong> (square roots, logarithms, trigonometric functions, factorials, etc.).</p>
</blockquote>
<p>The bolded part (emphasis in original) is really the key here. Sure, these functions aren't in the global namespace, and they aren't privileged by having operator syntax (e.g. <code>5!</code> instead of <code>factorial(5)</code>. But except for factorial (which as mentioned elsewhere, you rarely want to actually evaluate), all of these functions are in the <strong>standard library</strong> of any respectable general-purpose language.</p>
<p>So the question is really why to have these functions behind a qualified name or an import. But it costs the programmer almost no extra work to write <code>Math.sqrt</code> instead of <code>sqrt</code>, or <code>import static Math.*;</code> if really necessary; so there is very little practical difference, and therefore little justification is needed.</p>
<p>Avoiding pollution of the global namespace is a sufficient reason. Especially nowadays, IDEs offer code completion hints for names that are in scope, and the vast majority of programmers don't want to be offered the <code>sin</code> function every time they write <code>s</code> and press Tab. It would be especially annoying if every time you wanted to log a warning or an error, you were offered the math functions <code>log</code>, <code>log2</code> and <code>log10</code>.</p>

CC BY-SA 4.0
2023-11-13T18:26:51.613Z
2023-11-13T18:26:51.613Z
kaya3
CC BY-SA 4.0
2023-11-13T18:31:41.500Z
Why is it ok to have exponents (e.g. `5**3`) built into Python without the need for a library, but not trig functions? I totally disagree that having to type `Math.sin` costs nothing, because it makes code unnecessarily long and ugly. Those import statements also add up, to the point where files often have so many to scroll through in order to just read the first line of the "actual" code.
Nike Dattani
CC BY-SA 4.0
2023-11-13T18:38:12.827Z
@NikeDattani So you disagree with something I haven't said: I said it costs very little, not that it costs nothing. And personally I think `Math.sin` is *more* readable than just `sin`, because many people will not know that `sin` by itself is a math function. Your question "why is it OK?" about `**` in Python makes little sense to me ─ it is OK either way, of course, the rationale for having it one way is not because the other way wouldn't be "OK".
kaya3
CC BY-SA 4.0
2023-11-13T21:02:01.280Z
@NikeDattani: Python's use of `**` for exponentiation dates back to FORTRAN, and having code built into the compiler to recognize patterns like `(EXPRESSION)**2` was simpler and more flexible than having a special syntax for things like "compute square of value".  A more interesting question might be why LOG2 and EXP2 functions aren't more common, since the easiest way to perform a LOG or EXP function would be to normalize the operand into the range 1..exponent (for LOG) or 0..1 (for EXP), and normalization is easier with an exponent of 2 than with any other.
supercat
CC BY-SA 4.0
2023-11-13T21:26:20.783Z
@supercat but that is exactly my point! Python has `**` just like FORTRAN, but does not have `sin` or `cos` or `sqrt` without having to `import math` and to write `Math.sin` and `Math.cos`. If Python has `**` because FORTRAN has it, then let's remember that `SQRT` and `SIN` and `COS` are all ["Fortran intrinsic functions"](https://pages.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/funct.html) which do not need anything like a  `import math` command or a `Math.` at the beginning of each function. Also, I'm curious if your username refers to the Jamaican reggae DJ from the 1990s. I listened to him!
Nike Dattani
CC BY-SA 4.0
2023-11-13T21:48:11.960Z
@NikeDattani: Never heard of the artist you mention.  The trig functions happen to be  baked into FORTRAN implementations, but that's because many linker-related concepts--like the notion of a "standard library"--hadn't been invented yet.
supercat
CC BY-SA 4.0
2023-11-14T18:40:10.167Z
@supercat Is that really relevant? Some of those functions Fortran will actually use the libmath.so of the corresponding C compiler. Who cares? The Fortran compiler will just link it. The con is that when a linking C program using the `gfortran` command you can actually ommit many of the libraries you have to list when linking with `gcc` because they are being added automatically.
Vladimir F Героям слава
CC BY-SA 4.0
2023-11-14T19:30:49.030Z
@VladimirFГероямслава: FORTRAN was invented a loooong time ago, and it had to be usable on a machine which had no mass storage other than a punched card reader and a card punch.  Having a little bit of bespoke logic to either load routines like SQRT from punched cards or else skip over them, based upon whether a program used them, would have been cheaper than trying to have a general-purpose linker which could operate without a tape or disk drive.  The notion of a standard library makes sense on machines with disk drives, but FORTRAN predates such technologies.
supercat
CC BY-SA 4.0
2023-11-15T02:14:33.390Z
Another example where the namespacing is useful: `Math.tan` for a trig function versus `Color.tan` for a pale shade of brown.
dan04
CC BY-SA 4.0
2023-11-15T10:47:57.293Z
@dan04 do you mean `Math.tan()` vs `Color.tan`?
Nike Dattani
CC BY-SA 4.0
2023-11-15T11:32:37.687Z
@NikeDattani One of the best reasons: "It would be esp. annoying if every time you wanted to log a warning or an error, you were offered the math functions log, log2 and log10" Yes! The majority of programmers actually work on business software. Scientific or engineering software is niche, data science craze is too recent to have influenced major PLs. Business programmers just use addition and sometimes multiplication. Division could be suppressed, in most cases this would go unnoticed. So sin, cos, log, etc., are just alien cumbersome gizmos for the majority of programmers.
Jean-Armand Moroni
CC BY-SA 4.0
2023-11-16T01:18:15.717Z
@NikeDattani: As a note, you *don't* have to type `math.sin(x)` in Python if you don't want to. Python, like many languages, allows you to denamespace. All you change is the top of your file, from `import math` to `from math import sin, cos, tan` (whatever you want to explicitly have access to) or if you're a saucy sort who doesn't mind cluttering the global namespace with tons of stuff you don't need (including shadowing a useful built-in `pow` with a useless `math.pow`), `from math import *`. Is a single denamespacing import in files that need trigonometric functions a lot *so* terrible?
ShadowRanger
<p>It's almost entirely down to history of programming languages. For example, the <a href="https://www.evanmiller.org/statistical-shortcomings-in-standard-math-libraries.html" rel="nofollow noreferrer">Elusive Eight</a> are generally not included in languages because they were not included in C, and one can argue that this is because they were not present in BCPL, B, FORTRAN, COBOL, ALGOL, etc.</p>
<p>From a language-design perspective, numerical methods are usually based around IEEE 754, and this means that even basic transcendental operations are usually kicked out to a library, as they aren't defined by the standard.</p>
<h3>Aside: on Python</h3>
<blockquote>
<p>Namespaces are one honking great idea – let's do more of those! ~ <a href="https://en.wikipedia.org/wiki/Zen_of_Python" rel="nofollow noreferrer">Tim Peters</a></p>
</blockquote>
<p>Python has three features that aren't universal:</p>
<ul>
<li>Imports may occur mid-module</li>
<li>Imported modules can access foreign or native code</li>
<li>Functions can inspect the implementation details of arguments</li>
</ul>
<p>Benefiting from these features, Python sensibly uses <code>math</code> and friends to organize code into namespaces, so that the global scope is less polluted. <strong>Your design requirements around scoping and naming will constrain your day-to-day syntax,</strong> including syntax for numerical methods.</p>
<p>I designed the <code>Double</code> and <code>Int</code> types for <a href="https://github.com/monte-language/monte/" rel="nofollow noreferrer">Monte</a>, a dialect of <a href="https://en.wikipedia.org/wiki/E_(programming_language)" rel="nofollow noreferrer">E</a> designed to integrate various ideas from Python. We did not want to make any of those three assumptions, and <strong>we didn't want to pollute global scopes</strong>, so instead all of the necessary functionality is baked into methods on each type's classes. This forced the various mentioned functions to all be methods:</p>
<ul>
<li><code>squareRoot</code></li>
<li><code>exponential</code>, <code>logarithm</code> with optional base</li>
<li><code>sine</code>, <code>cosine</code>, <code>tangent</code>, <code>cosecant</code>, <code>secant</code>, <code>cotangent</code>, <code>arcSine</code>, etc.</li>
<li><a href="https://en.wikipedia.org/wiki/Atan2" rel="nofollow noreferrer">two-argument</a> <code>arcTangent</code></li>
</ul>
<p>And also the Elusive Eight:</p>
<ul>
<li><code>cumulativeBeta</code>, <code>quantileBeta</code></li>
<li><code>cumulativeGamma</code>, <code>quantileGamma</code></li>
<li><code>cumulativeNormal</code>, <code>quantileNormal</code></li>
<li><code>besselFirst</code></li>
</ul>
<p>Many of those were available <em>because</em> Monte is built upon Python. That's the core of my first paragraph: <strong>we build upon the standard libraries of our host languages</strong>. (Source code for these methods is available <a href="https://github.com/monte-language/typhon/blob/master/typhon/objects/data.py#L360" rel="nofollow noreferrer">here</a>.)</p>
<h3>Aside: on numerical methods</h3>
<p>I also included a method <code>euclidean</code> in Monte. This method computes the <a href="https://en.wikipedia.org/wiki/Euclidean_distance" rel="nofollow noreferrer">Euclidean distance</a> for a triangle. In Python code, a user might write:</p>
<pre><code>def euclidean(x, y): return math.sqrt(x * x + y * y)
</code></pre>
<p>However, this is not very accurate! I used <a href="https://herbie.uwplse.org/" rel="nofollow noreferrer">Herbie</a>, which used to tell me to do <a href="https://github.com/monte-language/typhon/blob/master/typhon/objects/data.py#L541" rel="nofollow noreferrer">this (ASCII art)</a>, but currently recommends using the builtin <a href="https://en.cppreference.com/w/c/numeric/math/hypot" rel="nofollow noreferrer"><code>hypot</code></a>, a procedure/template/macro available throughout the C/C++ world. Here is a good example of the main tradeoff to consider:</p>
<ul>
<li>You implement the numerical algorithms. Your users get to benefit from direct good support for each algorithm, with high-quality results and decent performance, but they are limited to what you choose to implement. <em>-- or --</em></li>
<li>Your users implement the algorithms. They have to work through arcane whitepapers and <a href="https://dlmf.nist.gov/" rel="nofollow noreferrer">DLMF</a>, but they get to implement whatever they want and have great performance.</li>
</ul>
<p>You also mentioned <a href="https://en.wikipedia.org/wiki/Kahan_summation_algorithm" rel="nofollow noreferrer">Kahan summation</a>. This is a good example of something I made <a href="https://github.com/monte-language/typhon/blob/master/mast/lib/doubles.mt#L121" rel="nofollow noreferrer">users implement in high-level code</a>. Why? Because I don't want to give an opinion on how a list of numbers should be summed! I want the user to choose their own summation algorithm, and then to fold generically over it. Here is more advice for language designers: <strong>It's less work for me and more control for the user.</strong></p>

CC BY-SA 4.0
2023-11-13T18:20:28.670Z
2023-11-16T01:03:39.853Z
2023-11-16T01:03:39.853Z
Corbin
CC BY-SA 4.0
2023-11-14T01:32:57.440Z
**Comments have been [moved to chat](https://chat.stackexchange.com/rooms/149689/discussion-on-answer-by-corbin-why-do-so-many-programming-languages-not-have-a); please do not continue the discussion here.** Before posting a comment below this one, please review the [purposes of comments](/help/privileges/comment). Comments that do not request clarification or suggest improvements usually belong as an [answer](/help/how-to-answer), on [meta], or in [chat]. Comments continuing discussion may be removed.
lyxal
CC BY-SA 4.0
2023-11-14T07:23:01.850Z
What you describe as "assumptions" of Python are IMHO better described as "features": it's not that Python assumes that some other part of the system lets a program do those things, but rather, Python itself enables programs to do those things.
ruakh
CC BY-SA 4.0
2024-04-28T22:47:59.817Z
»However, this is not very accurate« is somewhat misleading – it works fine most of the cases (your code uses the exact same formula then), just for extreme cases it does something else. (Also, I wonder why your MIN has a different order of magnitude than your MAX?)
Paŭlo Ebermann
<h1><code>factorial</code> isn't useful</h1>
<p>Imperative programming languages don't have <code>factorial</code> built-in because, on its own, it <strong>isn't useful</strong>.</p>
<p>Considering that the factorial operator only takes integers (let's not get into the Gamma function here), <code>factorial(13)</code> is already beyond the range of a <code>uint32_t</code>, and <code>factorial(21)</code> is beyond a <code>uint64_t</code>. So there aren't many inputs that make sense: if you <em>really</em> needed a table of the first few factorials for something, it'd make sense to program just that: a lookup table, rather than a function.</p>
<p>Generally, anywhere that you'd use a factorial in mathematical theory, once you actually need to use it in practice it's generally paired with something else to cancel out most of the magnitude of it - say, dividing by a smaller factorial. If you just wrote out <code>factorial(103) / factorial(100)</code> in a &quot;normal&quot; programming language you'd get an overflow error, when what you meant was <code>103 * 102 * 101</code>.</p>
<p>Analysis languages - things like Mathematica - will have a factorial function built in because they can intelligently work out how to simplify the expression for you without running into overflows, and because they're built for situations where you're more likely to want to use that function directly.</p>
<p>On the other hand, when it comes to being <em>taught</em> the basics of programming, <code>factorial</code> is a perfect implementation exercise: it's simple, it demonstrates basic principles, it demonstrates recursion, it's easy to verify that the result is correct by hand.</p>
<p>Most of the simple, <em>useful</em>, and hard-to-implement math functions <em>are</em> built-in. And those that aren't will generally have a third-party library available for it. If something's not implemented by default, it's generally because it's easy to implement in terms of what <em>is</em> available, or because you need to tailor it to your use case in all but the most trivial of situations.</p>

CC BY-SA 4.0
2023-11-13T08:25:26.900Z
2023-11-13T08:25:26.900Z
Keiji
CC BY-SA 4.0
2023-11-14T01:34:07.857Z
**Comments have been [moved to chat](https://chat.stackexchange.com/rooms/149690/discussion-on-answer-by-keiji-why-do-so-many-programming-languages-not-have-a-b); please do not continue the discussion here.** Before posting a comment below this one, please review the [purposes of comments](/help/privileges/comment). Comments that do not request clarification or suggest improvements usually belong as an [answer](/help/how-to-answer), on [meta], or in [chat]. Comments continuing discussion may be removed.
lyxal
<p>Ultimately it comes down to convention and opinion: languages can't have a builtin for everything, and generally developers prefer to have smaller standard libraries with &quot;conventional&quot; functions for a variety of reasons (smaller footprint, less to maintain, better third-party implementations). Factorial just isn't a &quot;conventional&quot; function.</p>
<p>Anecdotally, I've written many programs in my lifetime and can't remember the last time I've ever needed <code>factorial</code>. Despite what some people claim, most general-purpose programming doesn't involve anything beyond basic arithmetic, even exponents are rare.</p>
<p>Another reason <code>factorial</code> isn't builtin is that the optimal implementation (assuming tail call recursion) is very trivial and only a few lines of code; it takes 10 seconds to write and the footprint is almost nothing. The opposite is why builtins like <code>sin</code> and <code>cos</code> exist even though they're rarely used.</p>
<p>You'll also notice other languages' standard libraries missing seemingly-common functions, like <code>shuffle</code>, <code>binary_search</code> (and binary search trees), and regular expressions. <code>shuffle</code> and <code>binary_search</code> are simple enough for developers to write themselves, and regular expressions are better suited for third-party libraries due to having many implementations with different semantics.</p>

CC BY-SA 4.0
2023-11-13T02:16:32.830Z
2023-11-13T02:16:32.830Z
tarzh
CC BY-SA 4.0
2023-11-13T04:10:02.280Z
+1 but factorial was just an example and I'm wondering why basic math (e.g. square roots, logarithms, trig functions) isn't available by default. Is the answer precisely the same? You can't remember the last time you used a square root or a log(x) or a sin(x) when programming? What about powers? Powers are available in most languages but I don't think they're used much for programs that don't involve enough math that requires the other functions. Finally, I can't remember the last time I used a `GO TO` or a `WHILE` loop, but that doesn't mean they're not useful to others: these are available.
Nike Dattani
CC BY-SA 4.0
2023-11-13T05:36:13.907Z
Most standard libraries have `sqrt`, `log`, and basic trig ([`sin`, `cos`, `tan`, `arcsin`, `arccos`, `arctan`, `atan2`](https://langdev.stackexchange.com/a/1767/43)). It's also true that some "conventional" standard library functions like powers are trivial and rare; enough so that there's probably no good reason why they are included but others like `factorial` isn't.
tarzh
CC BY-SA 4.0
2023-11-13T05:37:41.150Z
@NikeDattani "basic math" is generally addition, subtraction, division, and multiplication. Anything else is much less common. Of course there are going to be cases where you use those other things all the time (eg, doing something dealing with determining trajectories or orbits), but those are more specialized areas. I'm a bit surprised at your claim of not having used a `while` loop in a long time.
Herohtar
CC BY-SA 4.0
2023-11-13T05:42:52.437Z
This section is also relevant: https://en.m.wikipedia.org/wiki/Sine_and_cosine#Software_implementations
Herohtar
CC BY-SA 4.0
2023-11-13T05:45:02.580Z
Ultimately I think a lot of small programming language decisions, including this one, are simply "early language designers decided to do it that way, and everyone else followed them". There are some things which every language does the same way, and there's a really good reason why (e.g. most of the compiler, lambda calculus, and type theory basics, which "fit together" like a clever mathematical proof, and any deviation makes everything slower and harder to implement). But there are other things which every language does the same way for no good reason, it's just the safest and default way.
tarzh
CC BY-SA 4.0
2023-11-13T07:21:41.503Z
`sin` and `cos` may not be functions you use a lot, but they're essential to computer graphics. Perhaps it's a lack of imagination on my part, but I don't think `factorial` has a similar domain need.
Jack Aidley
CC BY-SA 4.0
2023-11-13T07:27:34.757Z
A naive loop is *not* the optimal implementation of factorial for reasonably large `n`. [See for example](https://stackoverflow.com/questions/9815252).
Karl Knechtel
CC BY-SA 4.0
2023-11-13T07:28:50.400Z
@JackAidley factorials are used by people who have to solve combinatorics problems, which in turn may be part of computing probabilities in complex models. I can find [~11 thousand hits](https://github.com/search?q=%22from+math+import+factorial%22+language%3APython&type=code) on GitHub code search for `from math import factorial` in Python projects.
Karl Knechtel
CC BY-SA 4.0
2023-11-13T08:49:50.007Z
C++ has `std::binary_search`, `std::shuffle`, and `std::regex`, for example.
Brad Jones
CC BY-SA 4.0
2023-11-13T12:56:21.870Z
_"The opposite is why builtins like sin and cos exist even though they're rarely used."_ - Most languages do not have sin and cos as part of the language. They are usually part of the standard library, along with more esoteric functions (such as factorial).
marcelm
CC BY-SA 4.0
2023-11-13T18:13:29.083Z
@NikeDattani Powers of 2 are quite often used in (certain) programs, along with bitwise and/or/xor.
BlackJack
CC BY-SA 4.0
2023-11-13T18:38:33.680Z
@BlackJack sin() and cos() are also used a lot in "certain programs".
Nike Dattani
CC BY-SA 4.0
2023-11-13T19:41:23.447Z
@JackAidley: `sin` and `cos` are also essential for audio, due to sound waves being modeled as Fourier series.
dan04
CC BY-SA 4.0
2023-11-14T02:20:33.630Z
@BlackJack In my (admittedly limited) experience people don't usually use exponentiation when squaring, they bitshift or multiply. That said, I agree with this answer
user
CC BY-SA 4.0
2023-11-14T14:35:42.623Z
Yes I think this answer is the most plausable for most design decisions. Preferably, a language has a great system for installing packages/libraries because that allows the core language developers to push as much out of the core as possible. They typically do this because the core is a very slow moving object which needs to satisfy as many people as possible and because it's not easy to mix and match different implementations when everything is bundled in the core. Also, patches in libraries can be on client computers within days whereas a core language update usually takes much longer.
RikH
CC BY-SA 4.0
2023-11-14T17:30:12.150Z
@JackAidley Which is great if you're doing computer graphics.  Most processors in the world live in embedded systems - car body electronics, dishwashers, ovens, and so on.  How often do you think they need to do fancy graphics?  The same argument you use against factorials is equally true for trigonometry.
Graham
CC BY-SA 4.0
2023-11-15T01:04:51.360Z
@dan04 It would be very, very rare that you actually use sin and cos in any implementation of fourier transformation. In your maths book, yes.
gnasher729
CC BY-SA 4.0
2024-04-28T22:26:34.543Z
@KarlKnechtel looking at the first few results of that Github search, they are either for solving project Euler's "sum of digits of factorial", getting a list of all permutations of 1..n (and I think that can be done faster), benchmarking (or comparing results) against a separate factorial implementation, calculating the binomial coefficient (which is faster done differently). I doubt these are good reasons to have this in the standard library.
Paŭlo Ebermann
CC BY-SA 4.0
2024-09-10T21:42:01.010Z
@Graham: What's funny is that most common applications involving trig functions would be far better served using either degrees or revolutions as units than using radians.  Range reduction for a function with period 1 is much easier than for a function with period 2π. and it's far more likely that one would want to e.g. rotate a shape by exactly 90 degrees than by the floating point value closest to π/2 radians.
supercat
<p>There are three places where a language designer can choose to place some functionality:</p>
<ul>
<li>language core (e.g. operator)</li>
<li>standard library</li>
<li>leave it for third-party libraries</li>
</ul>
<p>Putting something into the language core has a huge cost (define the syntax and semantics, have a parser, have a special path for it in the code generator, have support in tools like IDEs etc.), so you do it only for features that you consider essential for a broad range of users.</p>
<p>Putting it into the standard library is less demanding, as from source code structure, it is &quot;just&quot; one more available function. But being &quot;standard&quot;, you require each and every implementation of the language now and in the future to support it.</p>
<p>Leaving it to third-party is the easiest way, if the &quot;base language&quot; allows for a decent implementation. This is surely true for factorial, but e.g. close to impossible for things like multi-threading.</p>
<p>But even your factorial examples has its own twists. Already 21! is so large a number that it no longer fits into a standard long integer.</p>
<p>So what would you expect the &quot;built-in&quot; factorial to do? Produce nonsense for anything beyond 20? Return variable-length integers (e.g. BigInteger in Java)? Does your language core (not the standard library) even have such integers?</p>
<p>So, any &quot;normal&quot; (long integer) factorial function can do nothing more than return one of 21 fixed, well-known values, and can be simply replaced by a pre-filled 21-elements array, with values e.g. found in <a href="https://en.wikipedia.org/wiki/Factorial" rel="noreferrer">Wikipedia's Factorial entry</a></p>
<p>And by providing an factorial out-of-the-box you'd deprive CS teachers of their favorite recursive-programming example.</p>

CC BY-SA 4.0
2023-11-13T08:27:23.380Z
2023-11-13T08:27:23.380Z
Ralf Kleberhoff
CC BY-SA 4.0
2023-11-13T22:17:16.573Z
Also add: "Putting something into the language core also means you "lock in" the semantics, including the performance/accuracy trade-offs, and algorithms. It also means nobody can ever make a replacement with that name."
"Putting it into the standard library means the semantics are slightly easier to change, and that replacements with the same name can be added later as replacements." (C++'s `rand` being an excellent example)
"Leaving it to third-parties means the samantics are trivial to change, and offer infinite selection of performance/accuracy trade-offs"
Mooing Duck
CC BY-SA 4.0
2023-11-14T18:32:57.927Z
Even with library fumctions you have a choice. You may require some `use math` or `#include <math.h>` or you can just let them available by default as built-ins. In Fortran the basic math functions, including the gamma function some Besel functions and similar, are intrinsic, you do not have to import any module (for certain more specialized things like IEEE754 stuff one does actually import a module with `use ieee_arithmetic` and similar).
Vladimir F Героям слава
CC BY-SA 4.0
2023-11-15T01:02:46.273Z
In Swift, + - * / are not even part of the language, but part of the standard library. Same as && || ! and others.
gnasher729
<p>Processors have several units, the most important for this discussion being the ALU, and its coprocessor, the FPU. The ALU is the part of the processor that does math. It has at most four math operations: addition, subtraction, multiplication, and division (note: subtraction, multiplication, and division are mutations of addition). As an example, RISC processors only have addition, subtraction, and multiplication, so if you want to divide, you have to use other tricks. The language needs to address those on a per-target basis.</p>
<p>After that, languages have to decide if they're going to support the FPU, which has functions like <span class="math-container">$cos(x)$</span> and <span class="math-container">$2^x-1$</span>. The FPU only has a limited amount of space, so engineers choose the most popular functions they can optimize. There's something like 20-30 of these function in a typical FPU, plus some useful constants like <span class="math-container">$\pi$</span>. The main functions on an FPU are centered around trigonometric functions, because those are the most useful functions outside of the four basic math operations.</p>
<p>In a typical language, the core syntax assumes a functional ALU, and provides syntax that will directly convert to machine code for a platform. For most functions outside of that, the programmers will often choose to write a library, mostly so they don't have to keep recompiling the compiler itself. The compiler may need to provide a <span class="math-container">$cos(x)$</span> function in software if there is no FPU or the FPU does not support it. Same goes for all the other trig functions. Executing functions in software is always slower than hardware, so the language should prioritize using hardware resources when available. Everything else will need to be in a library, no matter if it is built-in or not, because there is no hardware support for it.</p>
<p>Also, your question assumes that storage space is apparently unlimited across all devices. As a simple counterexample, consider this: you can write a program in C that will run with 32kb of ROM and 2kb of RAM (the classic NES system), but you cannot, to the best of my knowledge, do so in Java. Java is a great language, but doesn't fit all sizes. C is also a great language, but may not be the best in certain domain-specific languages. And that's the point. The design of the language is meant to fit a certain domain.</p>
<p>I've written code in dozens of languages over the last 35 years or so, and I can say that, with some confidence, most programs don't need trig functions. Also, I've never used factorial outside of learning how recursive functions work. The industry agrees--no processor out there that I'm aware of has native support for factorial calculation, so every language that provides it does so through an algorithm in a library.</p>
<p>There's also something to say for special exceptions. The more things you provide as an automatic built-in, the more exceptions you're making for the general purpose of the compiler. A more complicated compiler means better chances for bugs. By putting some of the more advanced math functions in a library, the cleaner your compiler will be.</p>
<p>I could make an argument for FPU-supplied functions being built-in, particularly <span class="math-container">$\sqrt{x}$</span> and such that are wildly useful, but again, they're kind of limited, as you don't even have <span class="math-container">$\sqrt[3]{x}$</span> in any FPU, so you'd still be stuck with writing custom logic to handle these kinds of operations. And, as I said previously, there's no guarantee you'll have an FPU to lean on for these operations. Aside from that, we only have so many characters on a standard keyboard, so at some point, someone has to draw a line about what built-in options we should have.</p>
<p>So, you could say that the reason why most languages don't include these by default is that hardware support is only &quot;guaranteed&quot; for about 3-4 mathematical operations, and everything else might have to be emulated in software, and that is easier done with a library framework. It is simply impractical to include more advanced maths when they're unnecessary most of the time. Most programs only need basic math (the main four), and if you need more, you're going to end up with a library of useful functions that can be better ported as a library rather than a core compiler feature.</p>

CC BY-SA 4.0
2023-11-13T05:42:42.967Z
2023-11-13T05:42:42.967Z
phyrfox
CC BY-SA 4.0
2023-11-13T06:16:16.933Z
The language does not have to decide to support an FPU; it can simply specify the operations and leave the implementation to the implementers.
Peter - Reinstate Monica
CC BY-SA 4.0
2023-11-14T18:22:32.613Z
I would like to upvote this, because it gets an important aspect of why the dividing line between "language" and "library" is where it is, but it contains a serious error. FPUs generally are just like ALUs, except that they implement floating-point instead of integer arithmetic. They _don't_ provide anything besides the four basic math operations (add, subtract, multiply, divide), _maybe_ square root, and ancillary functions like "round". Some historical designs didn't even include multiply and divide! The 80387, with its collection of logarithmic and trigonometric functions, is an outlier.
zwol
CC BY-SA 4.0
2023-11-14T23:14:44.983Z
In the 1990s, Dallas Semiconductor used to sell "iButton" devices that were a bit smaller than a 2032 coin cell that ran Java, using a microcontroller with IIRC 6KB of RAM.  Not quite the 2KB of an NES, but still pretty tiny.
supercat
CC BY-SA 4.0
2023-11-15T01:08:29.977Z
Around the 68040 processor, Motorola announced that their processors were faster at calculating sin, cos etc "by hand" than using the hardware functionality in their coprocessors. @zwol Very common in modern processors is "fused multiply-add" which calculates a*b + c with a single rounding error and usually much faster than a separate multiplication and addition.
gnasher729
<p><em>Disclaimer: <a href="https://langdev.stackexchange.com/a/3163/874">@Ralf Kleberhoff's answer</a> provides the key distinction made here.</em></p>
<p><strong>TL;DR: Cost and Convenience.</strong></p>
<p>There are 3 possible places for functionality to be defined:</p>
<ol>
<li>Language, ie built-in.</li>
<li>Standard library.</li>
<li>Third-party libraries.</li>
</ol>
<h3>Should they be in the core language?</h3>
<p>In general, the <em>cost</em> of maintaining any implementation in the language is high, and the <em>convenience</em> is low. Specifically:</p>
<ul>
<li>Built-ins typically require a <em>lot</em> of boiler-plate: special keywords/identifiers in the syntax, special mapping from syntax to semantics, special mapping from semantics to code generation, ...</li>
<li>Furthermore, built-in are opaque. Since there is no &quot;source&quot; code for them, the user will not be able to step into them with their debugger, or even merely read the code to check their correctness, or get inspiration.</li>
<li>Finally, built-in are &quot;carved in stone&quot;. Any change to their functionality may break a user<sup>1</sup>.</li>
</ul>
<p>Hence, between being costly/inconvenient for implementers and inconvenient for users, there is a strong incentive to limit the number of built-ins in most languages.</p>
<p><sup>1</sup> <em>Obligatory <a href="https://xkcd.com/1172/" rel="nofollow noreferrer">xkcd reference</a>.</em></p>
<h3>Should they be in the standard library?</h3>
<p>Certainly, <strong>if</strong> they are worth it.</p>
<p>The economics are much different for a standard library -- hence why a standard library typically has <em>many</em> more functions than a language has built-ins:</p>
<ul>
<li>The cost is not null, but way down.</li>
<li>The source code is available, both for casual inspection and debugging.</li>
<li>The functionality, though, is still &quot;carved in stone&quot;.</li>
</ul>
<p>For example, even though the Rust standard library is relatively <em>lean</em>, there's still a somewhat length <a href="https://doc.rust-lang.org/nightly/std/f64/consts/index.html" rel="nofollow noreferrer">list of constants</a> defined: the cost is near nil, and constants are, well, constant over time.</p>
<p>Still, many standard libraries will <em>not</em> have factorial in mainstream languages, why?</p>
<p>Because even though it would probably be fairly low cost, it's also fairly useless <em>for the target usages</em> of these languages. This means very low user demand, and thus they are not judged to be worth the trouble.</p>
<p>This changes, obviously, for mathematically-focused languages.</p>
<h3>Should they be in third-party libraries?</h3>
<p>Yes!</p>
<p>None of the constraints apply to third-party libraries: they only cost to people who use them, there can be a wide variety of implementations for different trade-offs, ...</p>

CC BY-SA 4.0
2023-11-13T10:05:39.980Z
2023-11-13T10:05:39.980Z
Matthieu M.
<p>At least some languages were designed to be small. Pascal was meant to be taught easily; C was meant to be ported easily. While the eventual size of the specification (language + libraries) may not be that different between a large language and a small language, the implementation effort is. A library can ideally simply be recompiled for a new target. These days, I suspect that the math libs are not the most portable libraries in the world because they cater to machine specific hardware; but on some old machines (my Atari ST, for example) floating point arithmetic was entirely written in software.</p>

CC BY-SA 4.0
2023-11-13T06:15:12.903Z
2023-11-13T06:15:12.903Z
Peter - Reinstate Monica
<p>One possible reason why C does this is because C has a concept of hosted and freestanding implementations. If an implementation is freestanding, then the standard libraries do not need to be provided. This leaves only the syntax of the language to perform tasks.</p>
<p>One reason for this is, while virtually any CPU is going to be able to add or subtract or multiply, not all of them, or at least, not all of the ones that C aims to support, are necessarily going to have capabilities to take the <code>sin</code> or <code>cos</code> or other complex functions of numbers. These implementations can just be freestanding and not need to include the standard libraries, and still be standards compliant.</p>

CC BY-SA 4.0
2023-11-13T22:44:50.533Z
2023-11-13T22:44:50.533Z
CPlus
CC BY-SA 4.0
2023-11-13T23:07:23.643Z
+1. Do CPU's do powers? Also, CPU's can't do `if / else` statements but the C language supports them, so it doesn't seem that being able to do it natively on the CPU is a requirement for the language to have a syntax for something!
Nike Dattani
CC BY-SA 4.0
2023-11-13T23:10:33.007Z
@NikeDattani A CPU could do integer powers by repeated multiplication rather easily. But I imagine fractional powers, which are required to be supported by `pow()`, would be much more complicated to implement. As `pow(2, 0.5)` would have to give an approximation of radical 2. CPUs typically implement `if / else` using branch/conditional jump instructions. Something like compare the condition with 0, and if it is equal, jump to the end of the `if` body.
CPlus
CC BY-SA 4.0
2023-11-13T23:11:48.440Z
@NikeDattani Things that typically cannot be implemented on the CPU are typically delegated to library functions, as is the case for copying memory blocks of arbitrary size. There is typically no instruction for that, so `memcpy()`.
CPlus
CC BY-SA 4.0
2023-11-13T23:13:58.133Z
I was thinking that `if / else` wasn't the best example, but isn't a lot of the C language not directly doable on a CPU? Fractional powers are possible in many languages (without calling a library), even though they can't natively be done on a CPU. Also, if integer powers are easy by repeated multiplication, then wouldn't factorial functions also be very easy?
Nike Dattani
CC BY-SA 4.0
2023-11-13T23:16:09.920Z
@NikeDattani Many languages that have exponentiation with fractional powers as an operator instead of a function are high-level languages whose interpreters are implemented in C and end up calling the C `pow()` function behind the scenes anyway. Factorial would be easy to implement, but I guess it's just not useful enough in most programs that the language designers thought it was worthwhile to require it.
CPlus
CC BY-SA 4.0
2023-11-13T23:21:06.620Z
@NikeDattani The only example of C statments that are not directly doable on the CPU that I can think of at this time would be assigning a structure to another structure of arbitrary size. That makes me wonder, is `memcpy()` redundant? Well, no, because the struct assignment is of a compile-time constant size so the compiler can emit a fixed number of `mov` instructions. But `memcpy()` can be of a runtime-determined size.
CPlus
CC BY-SA 4.0
2023-11-14T23:18:52.573Z
@user16217248: I would expect that many implementations of languages that have exponentiation operators would check whether the right-hand operand was a small integer constant and use bespoke logic for those cases rather than converting the right-hand operand to a floating-point value and calling `pow`.
supercat
CC BY-SA 4.0
2023-11-15T22:20:50.183Z
@user16217248: On the flip side, `memcpy` will often need to check at runtime to ascertain whether an operation can be performed as a sequence of word-sized moves, while structure assignment code would be able to ascertain that at compile time.
supercat
<p>Because most languages are programmed using a keyboard, and keyboards have a limited number of keys.</p>
<p>With the exception of APL and its derivatives- Uiua being notable for attempting to reinvent the entire operator set- languages are designed to be represented in the 7-bit ANSI character set: I'm not necessarily saying that's good.</p>
<p>However neither am I saying that that limitation is bad, particularly in view of the way that APL- initially relatively accessible using composed/overstruck characters- became an impenetrable mess when implementations stopped offering that as an input method.</p>

CC BY-SA 4.0
2023-11-13T17:56:55.520Z
2023-11-13T17:56:55.520Z
Mark Morgan Lloyd
CC BY-SA 4.0
2023-11-13T18:04:45.587Z
That's not really answering the question. Built-in way doesn't mean there has to be a symbol. Operators can be made of several characters, even letters.  See `sizeof` in C for instance. And the question would also include build-in functions, for which you don't need to import/include a library. Python for instance has a `pow()` function that doesn't need to be imported.
BlackJack
CC BY-SA 4.0
2023-11-14T19:00:17.350Z
Even `==` consists of two characters and it is a very widely used operator name
David Young
CC BY-SA 4.0
2023-12-03T18:48:31.017Z
Swift definitely allows non-ASCII characters in operator names. So use ≠ if you like.
gnasher729
<p>The bottom line is <strong>you can't have everything</strong>.</p>
<p>The <a href="https://www.evanmiller.org/statistical-shortcomings-in-standard-math-libraries.html" rel="noreferrer">&quot;elusive eight&quot; statistical functions</a> referenced in another answer might be absolutely essential to statisticians, but as a web application developer I've not only never needed them, I've <em>never heard of any of them</em>. You might say, &quot;well, you have now, so let's add them&quot;, but it's never that simple.</p>
<p>Even a very simple function needs many decisions:</p>
<ul>
<li>What are the types of its input and output?</li>
<li>What option flags or variations should be considered?</li>
<li>What are its failure cases, and how should those be handled?</li>
<li>Is any care needed to make it re-entrant, thread-safe, interruptible, etc?</li>
<li>Will the implementation, or even the behaviour, vary between target systems?</li>
</ul>
<p>That means every function has a cost, and <strong>the closer you put something to the core of a language, the higher the cost</strong>.</p>
<p>If you make the function intrinsic to the language, all of these have to be decided as part of the language design. Once defined, they are very hard to change; and once implemented, bugs have to be fixed by changes to the core language. If you are defining a language <em>specification</em>, every such function puts more work on those actually implementing it.</p>
<p>There are two main ways around this: you can <strong>specialise</strong>, or you can <strong>modularise</strong>.</p>
<p>If you want to <a href="http://www.codex99.com/design/the-hp35.html" rel="noreferrer">design a pocket calculator for engineers</a>, you might spend weeks hand-crafting integrated circuits for trigonometry and logarithms; that doesn't mean those are <em>easy</em> functions to implement, it means they are <em>important</em> for the use case you're targeting. In the same way, you can write a language optimised for anything from <a href="https://coq.inria.fr/" rel="noreferrer">proving mathematical theorems</a> to <a href="https://anydice.com/" rel="noreferrer">calculating the probability of complex dice rolls</a>. In each case, the things you <em>leave out</em> are as much a part of the definition as the things you <em>put in</em>.</p>
<p>If you don't want to specialise, you need some way of managing the vast range of different use cases someone might want to apply your language to. The principle way to do that is to make it <em>extendable</em> - allow the user to provide libraries of additional functions, with as little penalty as possible.</p>
<p>Ideally, it should be possible for those libraries to choose between optimised implementations, taking advantage of specific features of the target architecture; or portable ones, written with primitives provided by the language itself. That way, application authors can make use of either version without rewriting their code.</p>
<p>Finally, that brings us round to &quot;standard libraries&quot;, which are a compromise between language intrinsics and third-party extensions: they use the <em>mechanism</em> of the language's extension system, but are <em>standardised</em> across implementations. It's still costly to add functions to these, but easier to provide things like &quot;backports&quot; or &quot;polyfills&quot; for old or incomplete implementations, or work around <a href="https://en.wikipedia.org/wiki/Pentium_FDIV_bug" rel="noreferrer">a bug in the CPU's implementation of a crucial instruction</a>.</p>
<p>The ability to import a <code>math</code> or <code>stats</code> namespace with extra functions when you need them, is actually far <em>more</em> powerful than having a 1000-page language design document which tries to define every possible operation as an intrinsic keyword. Just as <a href="https://askubuntu.com/a/1296887/190923">distributing a package containing a single symlink</a> shows the power of a generalised package manager for an OS.</p>

CC BY-SA 4.0
2023-11-14T17:29:53.780Z
2023-11-14T17:29:53.780Z
IMSoP
# Why do so many programming languages not have a "built-in" way to do simple math functions?
Posted by: username_0 on 2023-11-12
**Note 1:** My question is not about the factorial function. It's about "simple math functions" that high-school level pocket calculators can do, but most programming languages cannot do ***without calling a library*** (square roots, logarithms, trigonometric functions, factorials, etc.).

**Note 2:** Comments and answers have said things like "by providing a factorial out-of-the-box you'd deprive CS teachers of their favorite recursive-programming example". While I agree that this joke is clever, it's unlikely that the developers of Java intentionally didn't include a factorial function so that CS teachers could have something to teach, so this isn't the type of answer I'm seeking.

---

# Preamble

I understand that not all programming languages can be like MATLAB, which *by default* allow users to write `factorial(10)` for 10!, `sqrt(10)` and for $\sqrt{10}$. Indeed, MATLAB, Mathematica, Maple, and other similar platforms, take up considerably more hard drive space than most compilers, even when combined with the space taken up by a typical heavy-weight IDE.

# However, even some of the least sophisticated *calculators* have a button for these simple functions.

Why would so many languages like Java and C++ (see [this StackOverflow thread if interested](https://stackoverflow.com/q/50132863/1271772)) not have a built-in way (i.e. ***without using a library***) to do the basic math that simple calculators can do?

# Related questions based on prior research:

* [Is there any particular reason to only include 3 out of the 6 trigonometry functions?](https://langdev.stackexchange.com/q/1765/34) (but the answers to that do not answer the question here).
* [Why programming languages does not have factorial function?](https://cseducators.stackexchange.com/q/7398/8966) (the answers say that such functions ***are not used much***, that they would be considered "***bloat***", and that language designers want to ***avoid putting a flag in the ground that says "this is how it's done"***; however my opinion is that these functions are common enough to be included in pocket calculators which have fewer KB of RAM than a computer, so they are not much "bloat", and if there's already a flag in the ground for multiplication and exponentiation I don't see why there can't be one for `sin()` or factorials).
**Tags:** syntax language-design compilers implementation math
> **Comments:**
> **username_1**: **Comments have been [moved to chat](https://chat.stackexchange.com/rooms/149687/discussion-on-question-by-nike-dattani-why-do-so-many-programming-languages-not); please do not continue the discussion here.** Before posting a comment below this one, please review the [purposes of comments](/help/privileges/comment). Comments that do not request clarification or suggest improvements usually belong as an [answer](/help/how-to-answer), on [meta], or in [chat]. Comments continuing discussion may be removed.  
> **username_2**: I think this question would be improved by explaining why you think programming languages should have the same features as calculators. Programming languages are not calculators: They are much more precisely specified, and are used for much more general tasks than calculators are.  
> **username_3**: Logint and square root can be done in nearly any language I know ...  
---
## 11 answers
### Answer by username_35 on 2023-11-14. Score: 38 | Accepted answer
The bottom line is **you can't have everything**.

The ["elusive eight" statistical functions](https://www.evanmiller.org/statistical-shortcomings-in-standard-math-libraries.html) referenced in another answer might be absolutely essential to statisticians, but as a web application developer I've not only never needed them, I've *never heard of any of them*. You might say, "well, you have now, so let's add them", but it's never that simple.

Even a very simple function needs many decisions:

* What are the types of its input and output?
* What option flags or variations should be considered?
* What are its failure cases, and how should those be handled?
* Is any care needed to make it re-entrant, thread-safe, interruptible, etc?
* Will the implementation, or even the behaviour, vary between target systems?

That means every function has a cost, and **the closer you put something to the core of a language, the higher the cost**.

If you make the function intrinsic to the language, all of these have to be decided as part of the language design. Once defined, they are very hard to change; and once implemented, bugs have to be fixed by changes to the core language. If you are defining a language *specification*, every such function puts more work on those actually implementing it.

There are two main ways around this: you can **specialise**, or you can **modularise**.

If you want to [design a pocket calculator for engineers](http://www.codex99.com/design/the-hp35.html), you might spend weeks hand-crafting integrated circuits for trigonometry and logarithms; that doesn't mean those are *easy* functions to implement, it means they are *important* for the use case you're targeting. In the same way, you can write a language optimised for anything from [proving mathematical theorems](https://coq.inria.fr/) to [calculating the probability of complex dice rolls](https://anydice.com/). In each case, the things you *leave out* are as much a part of the definition as the things you *put in*.

If you don't want to specialise, you need some way of managing the vast range of different use cases someone might want to apply your language to. The principle way to do that is to make it *extendable* - allow the user to provide libraries of additional functions, with as little penalty as possible.

Ideally, it should be possible for those libraries to choose between optimised implementations, taking advantage of specific features of the target architecture; or portable ones, written with primitives provided by the language itself. That way, application authors can make use of either version without rewriting their code.

Finally, that brings us round to "standard libraries", which are a compromise between language intrinsics and third-party extensions: they use the *mechanism* of the language's extension system, but are *standardised* across implementations. It's still costly to add functions to these, but easier to provide things like "backports" or "polyfills" for old or incomplete implementations, or work around [a bug in the CPU's implementation of a crucial instruction](https://en.wikipedia.org/wiki/Pentium_FDIV_bug).

The ability to import a `math` or `stats` namespace with extra functions when you need them, is actually far *more* powerful than having a 1000-page language design document which tries to define every possible operation as an intrinsic keyword. Just as [distributing a package containing a single symlink](https://askubuntu.com/a/1296887/190923) shows the power of a generalised package manager for an OS.
---
### Answer by username_14 on 2023-11-13. Score: 68
# `factorial` isn't useful

Imperative programming languages don't have `factorial` built-in because, on its own, it **isn't useful**.

Considering that the factorial operator only takes integers (let's not get into the Gamma function here), `factorial(13)` is already beyond the range of a `uint32_t`, and `factorial(21)` is beyond a `uint64_t`. So there aren't many inputs that make sense: if you *really* needed a table of the first few factorials for something, it'd make sense to program just that: a lookup table, rather than a function.

Generally, anywhere that you'd use a factorial in mathematical theory, once you actually need to use it in practice it's generally paired with something else to cancel out most of the magnitude of it - say, dividing by a smaller factorial. If you just wrote out `factorial(103) / factorial(100)` in a "normal" programming language you'd get an overflow error, when what you meant was `103 * 102 * 101`.

Analysis languages - things like Mathematica - will have a factorial function built in because they can intelligently work out how to simplify the expression for you without running into overflows, and because they're built for situations where you're more likely to want to use that function directly.

On the other hand, when it comes to being *taught* the basics of programming, `factorial` is a perfect implementation exercise: it's simple, it demonstrates basic principles, it demonstrates recursion, it's easy to verify that the result is correct by hand.

Most of the simple, *useful*, and hard-to-implement math functions *are* built-in. And those that aren't will generally have a third-party library available for it. If something's not implemented by default, it's generally because it's easy to implement in terms of what *is* available, or because you need to tailor it to your use case in all but the most trivial of situations.
> **Comments:**
> **username_11** (2023-11-14): **Comments have been [moved to chat](https://chat.stackexchange.com/rooms/149690/discussion-on-answer-by-keiji-why-do-so-many-programming-languages-not-have-a-b); please do not continue the discussion here.** Before posting a comment below this one, please review the [purposes of comments](/help/privileges/comment). Comments that do not request clarification or suggest improvements usually belong as an [answer](/help/how-to-answer), on [meta], or in [chat]. Comments continuing discussion may be removed.  
---
### Answer by username_15 on 2023-11-13. Score: 33
Ultimately it comes down to convention and opinion: languages can't have a builtin for everything, and generally developers prefer to have smaller standard libraries with "conventional" functions for a variety of reasons (smaller footprint, less to maintain, better third-party implementations). Factorial just isn't a "conventional" function.

Anecdotally, I've written many programs in my lifetime and can't remember the last time I've ever needed `factorial`. Despite what some people claim, most general-purpose programming doesn't involve anything beyond basic arithmetic, even exponents are rare.

Another reason `factorial` isn't builtin is that the optimal implementation (assuming tail call recursion) is very trivial and only a few lines of code; it takes 10 seconds to write and the footprint is almost nothing. The opposite is why builtins like `sin` and `cos` exist even though they're rarely used.

You'll also notice other languages' standard libraries missing seemingly-common functions, like `shuffle`, `binary_search` (and binary search trees), and regular expressions. `shuffle` and `binary_search` are simple enough for developers to write themselves, and regular expressions are better suited for third-party libraries due to having many implementations with different semantics.
> **Comments:**
> **username_0** (2023-11-13): +1 but factorial was just an example and I'm wondering why basic math (e.g. square roots, logarithms, trig functions) isn't available by default. Is the answer precisely the same? You can't remember the last time you used a square root or a log(x) or a sin(x) when programming? What about powers? Powers are available in most languages but I don't think they're used much for programs that don't involve enough math that requires the other functions. Finally, I can't remember the last time I used a `GO TO` or a `WHILE` loop, but that doesn't mean they're not useful to others: these are available.  
> **username_15** (2023-11-13): Most standard libraries have `sqrt`, `log`, and basic trig ([`sin`, `cos`, `tan`, `arcsin`, `arccos`, `arctan`, `atan2`](https://langdev.stackexchange.com/a/1767/43)). It's also true that some "conventional" standard library functions like powers are trivial and rare; enough so that there's probably no good reason why they are included but others like `factorial` isn't.  
> **username_16** (2023-11-13): @NikeDattani "basic math" is generally addition, subtraction, division, and multiplication. Anything else is much less common. Of course there are going to be cases where you use those other things all the time (eg, doing something dealing with determining trajectories or orbits), but those are more specialized areas. I'm a bit surprised at your claim of not having used a `while` loop in a long time.  
> **username_16** (2023-11-13): This section is also relevant: https://en.m.wikipedia.org/wiki/Sine_and_cosine#Software_implementations  
> **username_15** (2023-11-13): Ultimately I think a lot of small programming language decisions, including this one, are simply "early language designers decided to do it that way, and everyone else followed them". There are some things which every language does the same way, and there's a really good reason why (e.g. most of the compiler, lambda calculus, and type theory basics, which "fit together" like a clever mathematical proof, and any deviation makes everything slower and harder to implement). But there are other things which every language does the same way for no good reason, it's just the safest and default way.  
> **username_17** (2023-11-13): `sin` and `cos` may not be functions you use a lot, but they're essential to computer graphics. Perhaps it's a lack of imagination on my part, but I don't think `factorial` has a similar domain need.  
> **username_18** (2023-11-13): A naive loop is *not* the optimal implementation of factorial for reasonably large `n`. [See for example](https://stackoverflow.com/questions/9815252).  
> **username_18** (2023-11-13): @JackAidley factorials are used by people who have to solve combinatorics problems, which in turn may be part of computing probabilities in complex models. I can find [~11 thousand hits](https://github.com/search?q=%22from+math+import+factorial%22+language%3APython&type=code) on GitHub code search for `from math import factorial` in Python projects.  
> **username_19** (2023-11-13): C++ has `std::binary_search`, `std::shuffle`, and `std::regex`, for example.  
> **username_20** (2023-11-13): _"The opposite is why builtins like sin and cos exist even though they're rarely used."_ - Most languages do not have sin and cos as part of the language. They are usually part of the standard library, along with more esoteric functions (such as factorial).  
> **username_21** (2023-11-13): @NikeDattani Powers of 2 are quite often used in (certain) programs, along with bitwise and/or/xor.  
> **username_0** (2023-11-13): @BlackJack sin() and cos() are also used a lot in "certain programs".  
> **username_7** (2023-11-13): @JackAidley: `sin` and `cos` are also essential for audio, due to sound waves being modeled as Fourier series.  
> **username_22** (2023-11-14): @BlackJack In my (admittedly limited) experience people don't usually use exponentiation when squaring, they bitshift or multiply. That said, I agree with this answer  
> **username_23** (2023-11-14): Yes I think this answer is the most plausable for most design decisions. Preferably, a language has a great system for installing packages/libraries because that allows the core language developers to push as much out of the core as possible. They typically do this because the core is a very slow moving object which needs to satisfy as many people as possible and because it's not easy to mix and match different implementations when everything is bundled in the core. Also, patches in libraries can be on client computers within days whereas a core language update usually takes much longer.  
> **username_24** (2023-11-14): @JackAidley Which is great if you're doing computer graphics.  Most processors in the world live in embedded systems - car body electronics, dishwashers, ovens, and so on.  How often do you think they need to do fancy graphics?  The same argument you use against factorials is equally true for trigonometry.  
> **username_25** (2023-11-15): @dan04 It would be very, very rare that you actually use sin and cos in any implementation of fourier transformation. In your maths book, yes.  
> **username_13** (2024-04-28): @KarlKnechtel looking at the first few results of that Github search, they are either for solving project Euler's "sum of digits of factorial", getting a list of all permutations of 1..n (and I think that can be done faster), benchmarking (or comparing results) against a separate factorial implementation, calculating the binomial coefficient (which is faster done differently). I doubt these are good reasons to have this in the standard library.  
> **username_5** (2024-09-10): @Graham: What's funny is that most common applications involving trig functions would be far better served using either degrees or revolutions as units than using radians.  Range reduction for a function with period 1 is much easier than for a function with period 2π. and it's far more likely that one would want to e.g. rotate a shape by exactly 90 degrees than by the floating point value closest to π/2 radians.  
---
### Answer by username_26 on 2023-11-13. Score: 25
There are three places where a language designer can choose to place some functionality:

* language core (e.g. operator)
* standard library
* leave it for third-party libraries

Putting something into the language core has a huge cost (define the syntax and semantics, have a parser, have a special path for it in the code generator, have support in tools like IDEs etc.), so you do it only for features that you consider essential for a broad range of users.

Putting it into the standard library is less demanding, as from source code structure, it is "just" one more available function. But being "standard", you require each and every implementation of the language now and in the future to support it.

Leaving it to third-party is the easiest way, if the "base language" allows for a decent implementation. This is surely true for factorial, but e.g. close to impossible for things like multi-threading.

But even your factorial examples has its own twists. Already 21! is so large a number that it no longer fits into a standard long integer.

So what would you expect the "built-in" factorial to do? Produce nonsense for anything beyond 20? Return variable-length integers (e.g. BigInteger in Java)? Does your language core (not the standard library) even have such integers?

So, any "normal" (long integer) factorial function can do nothing more than return one of 21 fixed, well-known values, and can be simply replaced by a pre-filled 21-elements array, with values e.g. found in [Wikipedia's Factorial entry](https://en.wikipedia.org/wiki/Factorial)

And by providing an factorial out-of-the-box you'd deprive CS teachers of their favorite recursive-programming example.
> **Comments:**
> **username_27** (2023-11-13): Also add: "Putting something into the language core also means you "lock in" the semantics, including the performance/accuracy trade-offs, and algorithms. It also means nobody can ever make a replacement with that name."
"Putting it into the standard library means the semantics are slightly easier to change, and that replacements with the same name can be added later as replacements." (C++'s `rand` being an excellent example)
"Leaving it to third-parties means the samantics are trivial to change, and offer infinite selection of performance/accuracy trade-offs"  
> **username_6** (2023-11-14): Even with library fumctions you have a choice. You may require some `use math` or `#include <math.h>` or you can just let them available by default as built-ins. In Fortran the basic math functions, including the gamma function some Besel functions and similar, are intrinsic, you do not have to import any module (for certain more specialized things like IEEE754 stuff one does actually import a module with `use ieee_arithmetic` and similar).  
> **username_25** (2023-11-15): In Swift, + - * / are not even part of the language, but part of the standard library. Same as && || ! and others.  
---
### Answer by username_4 on 2023-11-13. Score: 9
> most programming languages cannot do ***without calling a library*** (square roots, logarithms, trigonometric functions, factorials, etc.).

The bolded part (emphasis in original) is really the key here. Sure, these functions aren't in the global namespace, and they aren't privileged by having operator syntax (e.g. `5!` instead of `factorial(5)`. But except for factorial (which as mentioned elsewhere, you rarely want to actually evaluate), all of these functions are in the **standard library** of any respectable general-purpose language.

So the question is really why to have these functions behind a qualified name or an import. But it costs the programmer almost no extra work to write `Math.sqrt` instead of `sqrt`, or `import static Math.*;` if really necessary; so there is very little practical difference, and therefore little justification is needed.

Avoiding pollution of the global namespace is a sufficient reason. Especially nowadays, IDEs offer code completion hints for names that are in scope, and the vast majority of programmers don't want to be offered the `sin` function every time they write `s` and press Tab. It would be especially annoying if every time you wanted to log a warning or an error, you were offered the math functions `log`, `log2` and `log10`.
> **Comments:**
> **username_0** (2023-11-13): Why is it ok to have exponents (e.g. `5**3`) built into Python without the need for a library, but not trig functions? I totally disagree that having to type `Math.sin` costs nothing, because it makes code unnecessarily long and ugly. Those import statements also add up, to the point where files often have so many to scroll through in order to just read the first line of the "actual" code.  
> **username_4** (2023-11-13): @NikeDattani So you disagree with something I haven't said: I said it costs very little, not that it costs nothing. And personally I think `Math.sin` is *more* readable than just `sin`, because many people will not know that `sin` by itself is a math function. Your question "why is it OK?" about `**` in Python makes little sense to me ─ it is OK either way, of course, the rationale for having it one way is not because the other way wouldn't be "OK".  
> **username_5** (2023-11-13): @NikeDattani: Python's use of `**` for exponentiation dates back to FORTRAN, and having code built into the compiler to recognize patterns like `(EXPRESSION)**2` was simpler and more flexible than having a special syntax for things like "compute square of value".  A more interesting question might be why LOG2 and EXP2 functions aren't more common, since the easiest way to perform a LOG or EXP function would be to normalize the operand into the range 1..exponent (for LOG) or 0..1 (for EXP), and normalization is easier with an exponent of 2 than with any other.  
> **username_0** (2023-11-13): @supercat but that is exactly my point! Python has `**` just like FORTRAN, but does not have `sin` or `cos` or `sqrt` without having to `import math` and to write `Math.sin` and `Math.cos`. If Python has `**` because FORTRAN has it, then let's remember that `SQRT` and `SIN` and `COS` are all ["Fortran intrinsic functions"](https://pages.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/funct.html) which do not need anything like a  `import math` command or a `Math.` at the beginning of each function. Also, I'm curious if your username refers to the Jamaican reggae DJ from the 1990s. I listened to him!  
> **username_5** (2023-11-13): @NikeDattani: Never heard of the artist you mention.  The trig functions happen to be  baked into FORTRAN implementations, but that's because many linker-related concepts--like the notion of a "standard library"--hadn't been invented yet.  
> **username_6** (2023-11-14): @supercat Is that really relevant? Some of those functions Fortran will actually use the libmath.so of the corresponding C compiler. Who cares? The Fortran compiler will just link it. The con is that when a linking C program using the `gfortran` command you can actually ommit many of the libraries you have to list when linking with `gcc` because they are being added automatically.  
> **username_5** (2023-11-14): @VladimirFГероямслава: FORTRAN was invented a loooong time ago, and it had to be usable on a machine which had no mass storage other than a punched card reader and a card punch.  Having a little bit of bespoke logic to either load routines like SQRT from punched cards or else skip over them, based upon whether a program used them, would have been cheaper than trying to have a general-purpose linker which could operate without a tape or disk drive.  The notion of a standard library makes sense on machines with disk drives, but FORTRAN predates such technologies.  
> **username_7** (2023-11-15): Another example where the namespacing is useful: `Math.tan` for a trig function versus `Color.tan` for a pale shade of brown.  
> **username_0** (2023-11-15): @dan04 do you mean `Math.tan()` vs `Color.tan`?  
> **username_8** (2023-11-15): @NikeDattani One of the best reasons: "It would be esp. annoying if every time you wanted to log a warning or an error, you were offered the math functions log, log2 and log10" Yes! The majority of programmers actually work on business software. Scientific or engineering software is niche, data science craze is too recent to have influenced major PLs. Business programmers just use addition and sometimes multiplication. Division could be suppressed, in most cases this would go unnoticed. So sin, cos, log, etc., are just alien cumbersome gizmos for the majority of programmers.  
> **username_9** (2023-11-16): @NikeDattani: As a note, you *don't* have to type `math.sin(x)` in Python if you don't want to. Python, like many languages, allows you to denamespace. All you change is the top of your file, from `import math` to `from math import sin, cos, tan` (whatever you want to explicitly have access to) or if you're a saucy sort who doesn't mind cluttering the global namespace with tons of stuff you don't need (including shadowing a useful built-in `pow` with a useless `math.pow`), `from math import *`. Is a single denamespacing import in files that need trigonometric functions a lot *so* terrible?  
---
### Answer by username_10 on 2023-11-13. Score: 9
It's almost entirely down to history of programming languages. For example, the Elusive Eight are generally not included in languages because they were not included in C, and one can argue that this is because they were not present in BCPL, B, FORTRAN, COBOL, ALGOL, etc.
From a language-design perspective, numerical methods are usually based around IEEE 754, and this means that even basic transcendental operations are usually kicked out to a library, as they aren't defined by the standard.
Aside: on Python

Namespaces are one honking great idea – let's do more of those! ~ Tim Peters

Python has three features that aren't universal:

Imports may occur mid-module
Imported modules can access foreign or native code
Functions can inspect the implementation details of arguments

Benefiting from these features, Python sensibly uses math and friends to organize code into namespaces, so that the global scope is less polluted. Your design requirements around scoping and naming will constrain your day-to-day syntax, including syntax for numerical methods.
I designed the Double and Int types for Monte, a dialect of E designed to integrate various ideas from Python. We did not want to make any of those three assumptions, and we didn't want to pollute global scopes, so instead all of the necessary functionality is baked into methods on each type's classes. This forced the various mentioned functions to all be methods:

squareRoot
exponential, logarithm with optional base
sine, cosine, tangent, cosecant, secant, cotangent, arcSine, etc.
two-argument arcTangent

And also the Elusive Eight:

cumulativeBeta, quantileBeta
cumulativeGamma, quantileGamma
cumulativeNormal, quantileNormal
besselFirst

Many of those were available because Monte is built upon Python. That's the core of my first paragraph: we build upon the standard libraries of our host languages. (Source code for these methods is available here.)
Aside: on numerical methods
I also included a method euclidean in Monte. This method computes the Euclidean distance for a triangle. In Python code, a user might write:
def euclidean(x, y): return math.sqrt(x * x + y * y)

However, this is not very accurate! I used Herbie, which used to tell me to do this (ASCII art), but currently recommends using the builtin hypot, a procedure/template/macro available throughout the C/C++ world. Here is a good example of the main tradeoff to consider:

You implement the numerical algorithms. Your users get to benefit from direct good support for each algorithm, with high-quality results and decent performance, but they are limited to what you choose to implement. -- or --
Your users implement the algorithms. They have to work through arcane whitepapers and DLMF, but they get to implement whatever they want and have great performance.

You also mentioned Kahan summation. This is a good example of something I made users implement in high-level code. Why? Because I don't want to give an opinion on how a list of numbers should be summed! I want the user to choose their own summation algorithm, and then to fold generically over it. Here is more advice for language designers: It's less work for me and more control for the user.
> **Comments:**
> **username_11** (2023-11-14): **Comments have been [moved to chat](https://chat.stackexchange.com/rooms/149689/discussion-on-answer-by-corbin-why-do-so-many-programming-languages-not-have-a); please do not continue the discussion here.** Before posting a comment below this one, please review the [purposes of comments](/help/privileges/comment). Comments that do not request clarification or suggest improvements usually belong as an [answer](/help/how-to-answer), on [meta], or in [chat]. Comments continuing discussion may be removed.  
> **username_12** (2023-11-14): What you describe as "assumptions" of Python are IMHO better described as "features": it's not that Python assumes that some other part of the system lets a program do those things, but rather, Python itself enables programs to do those things.  
> **username_13** (2024-04-28): »However, this is not very accurate« is somewhat misleading – it works fine most of the cases (your code uses the exact same formula then), just for extreme cases it does something else. (Also, I wonder why your MIN has a different order of magnitude than your MAX?)  
---
### Answer by username_28 on 2023-11-13. Score: 4
Processors have several units, the most important for this discussion being the ALU, and its coprocessor, the FPU. The ALU is the part of the processor that does math. It has at most four math operations: addition, subtraction, multiplication, and division (note: subtraction, multiplication, and division are mutations of addition). As an example, RISC processors only have addition, subtraction, and multiplication, so if you want to divide, you have to use other tricks. The language needs to address those on a per-target basis.

After that, languages have to decide if they're going to support the FPU, which has functions like $cos(x)$ and $2^x-1$. The FPU only has a limited amount of space, so engineers choose the most popular functions they can optimize. There's something like 20-30 of these function in a typical FPU, plus some useful constants like $\pi$. The main functions on an FPU are centered around trigonometric functions, because those are the most useful functions outside of the four basic math operations.

In a typical language, the core syntax assumes a functional ALU, and provides syntax that will directly convert to machine code for a platform. For most functions outside of that, the programmers will often choose to write a library, mostly so they don't have to keep recompiling the compiler itself. The compiler may need to provide a $cos(x)$ function in software if there is no FPU or the FPU does not support it. Same goes for all the other trig functions. Executing functions in software is always slower than hardware, so the language should prioritize using hardware resources when available. Everything else will need to be in a library, no matter if it is built-in or not, because there is no hardware support for it.

Also, your question assumes that storage space is apparently unlimited across all devices. As a simple counterexample, consider this: you can write a program in C that will run with 32kb of ROM and 2kb of RAM (the classic NES system), but you cannot, to the best of my knowledge, do so in Java. Java is a great language, but doesn't fit all sizes. C is also a great language, but may not be the best in certain domain-specific languages. And that's the point. The design of the language is meant to fit a certain domain.

I've written code in dozens of languages over the last 35 years or so, and I can say that, with some confidence, most programs don't need trig functions. Also, I've never used factorial outside of learning how recursive functions work. The industry agrees--no processor out there that I'm aware of has native support for factorial calculation, so every language that provides it does so through an algorithm in a library.

There's also something to say for special exceptions. The more things you provide as an automatic built-in, the more exceptions you're making for the general purpose of the compiler. A more complicated compiler means better chances for bugs. By putting some of the more advanced math functions in a library, the cleaner your compiler will be.

I could make an argument for FPU-supplied functions being built-in, particularly $\sqrt{x}$ and such that are wildly useful, but again, they're kind of limited, as you don't even have $\sqrt[3]{x}$ in any FPU, so you'd still be stuck with writing custom logic to handle these kinds of operations. And, as I said previously, there's no guarantee you'll have an FPU to lean on for these operations. Aside from that, we only have so many characters on a standard keyboard, so at some point, someone has to draw a line about what built-in options we should have.

So, you could say that the reason why most languages don't include these by default is that hardware support is only "guaranteed" for about 3-4 mathematical operations, and everything else might have to be emulated in software, and that is easier done with a library framework. It is simply impractical to include more advanced maths when they're unnecessary most of the time. Most programs only need basic math (the main four), and if you need more, you're going to end up with a library of useful functions that can be better ported as a library rather than a core compiler feature.
> **Comments:**
> **username_29** (2023-11-13): The language does not have to decide to support an FPU; it can simply specify the operations and leave the implementation to the implementers.  
> **username_30** (2023-11-14): I would like to upvote this, because it gets an important aspect of why the dividing line between "language" and "library" is where it is, but it contains a serious error. FPUs generally are just like ALUs, except that they implement floating-point instead of integer arithmetic. They _don't_ provide anything besides the four basic math operations (add, subtract, multiply, divide), _maybe_ square root, and ancillary functions like "round". Some historical designs didn't even include multiply and divide! The 80387, with its collection of logarithmic and trigonometric functions, is an outlier.  
> **username_5** (2023-11-14): In the 1990s, Dallas Semiconductor used to sell "iButton" devices that were a bit smaller than a 2032 coin cell that ran Java, using a microcontroller with IIRC 6KB of RAM.  Not quite the 2KB of an NES, but still pretty tiny.  
> **username_25** (2023-11-15): Around the 68040 processor, Motorola announced that their processors were faster at calculating sin, cos etc "by hand" than using the hardware functionality in their coprocessors. @zwol Very common in modern processors is "fused multiply-add" which calculates a*b + c with a single rounding error and usually much faster than a separate multiplication and addition.  
---
### Answer by username_31 on 2023-11-13. Score: 4
*Disclaimer: [@Ralf Kleberhoff's answer](https://langdev.stackexchange.com/a/3163/874) provides the key distinction made here.*

**TL;DR: Cost and Convenience.**

There are 3 possible places for functionality to be defined:

1. Language, ie built-in.
2. Standard library.
3. Third-party libraries.

### Should they be in the core language?

In general, the *cost* of maintaining any implementation in the language is high, and the *convenience* is low. Specifically:

* Built-ins typically require a *lot* of boiler-plate: special keywords/identifiers in the syntax, special mapping from syntax to semantics, special mapping from semantics to code generation, ...
* Furthermore, built-in are opaque. Since there is no "source" code for them, the user will not be able to step into them with their debugger, or even merely read the code to check their correctness, or get inspiration.
* Finally, built-in are "carved in stone". Any change to their functionality may break a user1.

Hence, between being costly/inconvenient for implementers and inconvenient for users, there is a strong incentive to limit the number of built-ins in most languages.

1 *Obligatory [xkcd reference](https://xkcd.com/1172/).*

### Should they be in the standard library?

Certainly, **if** they are worth it.

The economics are much different for a standard library -- hence why a standard library typically has *many* more functions than a language has built-ins:

* The cost is not null, but way down.
* The source code is available, both for casual inspection and debugging.
* The functionality, though, is still "carved in stone".

For example, even though the Rust standard library is relatively *lean*, there's still a somewhat length [list of constants](https://doc.rust-lang.org/nightly/std/f64/consts/index.html) defined: the cost is near nil, and constants are, well, constant over time.

Still, many standard libraries will *not* have factorial in mainstream languages, why?

Because even though it would probably be fairly low cost, it's also fairly useless *for the target usages* of these languages. This means very low user demand, and thus they are not judged to be worth the trouble.

This changes, obviously, for mathematically-focused languages.

### Should they be in third-party libraries?

Yes!

None of the constraints apply to third-party libraries: they only cost to people who use them, there can be a wide variety of implementations for different trade-offs, ...
---
### Answer by username_29 on 2023-11-13. Score: 3
At least some languages were designed to be small. Pascal was meant to be taught easily; C was meant to be ported easily. While the eventual size of the specification (language + libraries) may not be that different between a large language and a small language, the implementation effort is. A library can ideally simply be recompiled for a new target. These days, I suspect that the math libs are not the most portable libraries in the world because they cater to machine specific hardware; but on some old machines (my Atari ST, for example) floating point arithmetic was entirely written in software.
---
### Answer by username_32 on 2023-11-13. Score: 2
One possible reason why C does this is because C has a concept of hosted and freestanding implementations. If an implementation is freestanding, then the standard libraries do not need to be provided. This leaves only the syntax of the language to perform tasks.

One reason for this is, while virtually any CPU is going to be able to add or subtract or multiply, not all of them, or at least, not all of the ones that C aims to support, are necessarily going to have capabilities to take the `sin` or `cos` or other complex functions of numbers. These implementations can just be freestanding and not need to include the standard libraries, and still be standards compliant.
> **Comments:**
> **username_0** (2023-11-13): +1. Do CPU's do powers? Also, CPU's can't do `if / else` statements but the C language supports them, so it doesn't seem that being able to do it natively on the CPU is a requirement for the language to have a syntax for something!  
> **username_32** (2023-11-13): @NikeDattani A CPU could do integer powers by repeated multiplication rather easily. But I imagine fractional powers, which are required to be supported by `pow()`, would be much more complicated to implement. As `pow(2, 0.5)` would have to give an approximation of radical 2. CPUs typically implement `if / else` using branch/conditional jump instructions. Something like compare the condition with 0, and if it is equal, jump to the end of the `if` body.  
> **username_32** (2023-11-13): @NikeDattani Things that typically cannot be implemented on the CPU are typically delegated to library functions, as is the case for copying memory blocks of arbitrary size. There is typically no instruction for that, so `memcpy()`.  
> **username_0** (2023-11-13): I was thinking that `if / else` wasn't the best example, but isn't a lot of the C language not directly doable on a CPU? Fractional powers are possible in many languages (without calling a library), even though they can't natively be done on a CPU. Also, if integer powers are easy by repeated multiplication, then wouldn't factorial functions also be very easy?  
> **username_32** (2023-11-13): @NikeDattani Many languages that have exponentiation with fractional powers as an operator instead of a function are high-level languages whose interpreters are implemented in C and end up calling the C `pow()` function behind the scenes anyway. Factorial would be easy to implement, but I guess it's just not useful enough in most programs that the language designers thought it was worthwhile to require it.  
> **username_32** (2023-11-13): @NikeDattani The only example of C statments that are not directly doable on the CPU that I can think of at this time would be assigning a structure to another structure of arbitrary size. That makes me wonder, is `memcpy()` redundant? Well, no, because the struct assignment is of a compile-time constant size so the compiler can emit a fixed number of `mov` instructions. But `memcpy()` can be of a runtime-determined size.  
> **username_5** (2023-11-14): @user16217248: I would expect that many implementations of languages that have exponentiation operators would check whether the right-hand operand was a small integer constant and use bespoke logic for those cases rather than converting the right-hand operand to a floating-point value and calling `pow`.  
> **username_5** (2023-11-15): @user16217248: On the flip side, `memcpy` will often need to check at runtime to ascertain whether an operation can be performed as a sequence of word-sized moves, while structure assignment code would be able to ascertain that at compile time.  
---
### Answer by username_33 on 2023-11-13. Score: 0
Because most languages are programmed using a keyboard, and keyboards have a limited number of keys.

With the exception of APL and its derivatives- Uiua being notable for attempting to reinvent the entire operator set- languages are designed to be represented in the 7-bit ANSI character set: I'm not necessarily saying that's good.

However neither am I saying that that limitation is bad, particularly in view of the way that APL- initially relatively accessible using composed/overstruck characters- became an impenetrable mess when implementations stopped offering that as an input method.
> **Comments:**
> **username_21** (2023-11-13): That's not really answering the question. Built-in way doesn't mean there has to be a symbol. Operators can be made of several characters, even letters.  See `sizeof` in C for instance. And the question would also include build-in functions, for which you don't need to import/include a library. Python for instance has a `pow()` function that doesn't need to be imported.  
> **username_34** (2023-11-14): Even `==` consists of two characters and it is a very widely used operator name  
> **username_25** (2023-12-03): Swift definitely allows non-ASCII characters in operator names. So use ≠ if you like.  
---
