Skip to main content
68 votes

Why do so many programming languages not have a "built-in" way to do simple math functions?

factorial isn't useful Imperative programming languages don't have factorial built-in because, on its own, it isn't useful. ...
Keiji's user avatar
  • 607
38 votes
Accepted

Why do so many programming languages not have a "built-in" way to do simple math functions?

The bottom line is you can't have everything. The "elusive eight" statistical functions referenced in another answer might be absolutely essential to statisticians, but as a web application ...
IMSoP's user avatar
  • 2,428
34 votes
Accepted

How to ensure that an optimising compiler will terminate?

The roots of the problem: cost models, and monotonicity You're really getting at the heart of the problem when you say: each rewrite rule should make the program "more efficient" After all,...
Moonchild's user avatar
  • 879
33 votes

Why do so many programming languages not have a "built-in" way to do simple math functions?

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" ...
tarzh's user avatar
  • 3,924
29 votes

What are the pros and cons of single-pass compilers?

I’m going to assume this question is about ahead-of-time compilers; JIT compilers are a different story altogether. With that in mind… The performance benefits of single-pass compilers are overstated ...
Alexis King's user avatar
  • 8,731
25 votes

Why do so many programming languages not have a "built-in" way to do simple math functions?

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 ...
Ralf Kleberhoff's user avatar
21 votes

How to ensure that an optimising compiler will terminate?

The existing answer is good and representative of the techniques currently used in most optimizing compilers. I’d like to add to that by mentioning equality saturation, a newer technique that seems ...
Alexis King's user avatar
  • 8,731
15 votes
Accepted

What are the pros and cons of a compiler with a single-pass parser?

What constitutes a single-pass parser? Where you draw the line is somewhat arbitrary. Most programming languages tokenize their input and then parse the token stream; arguably this is already a multi-...
Alexis King's user avatar
  • 8,731
13 votes
Accepted

What are the pros and cons of interpreted programming languages?

I'll try to answer from the perspective of a language implementer/designer and as a user. I'll also try to answer as broadly and generally as possible, but disclaimer: these lists may not apply to ...
Gavin D. Howard's user avatar
13 votes
Accepted

Async Implementation

I'm able to implement a JS-like Promise system, but this doesn't help with running asynchronous C# functions, for example sending a HTTP request. Async/await is syntax sugar for promises. You'll need ...
tarzh's user avatar
  • 3,924
12 votes

What are the advantages/disadvantages of null-terminated strings vs length-prefixed strings?

Length-prefixed strings have the advantage of being able to find their length in O(1) time rather than O(n) time. This means you can find the end of the string more easily with the length prefix. They ...
Isaiah's user avatar
  • 789
11 votes

What are the advantages/disadvantages of null-terminated strings vs length-prefixed strings?

An option missing from the question is fat pointers ─ the type &str in Rust is an example of this. The length is not stored on the heap as a prefix to the ...
kaya3's user avatar
  • 19.7k
11 votes

What are the advantages/disadvantages of null-terminated strings vs length-prefixed strings?

Null-terminated strings can't include the null byte, whereas length-prefixed ones can include all 256 possible binary values.
pppery's user avatar
  • 920
11 votes

How can I infer the type of an empty literal?

As you said, "unknown" is a placeholder. It holds the place for a concrete type that has not yet been seen. When you see ["hello"] + [], you're ...
zdimension's user avatar
11 votes

How are hand-written parsers organised, and how do they work?

The most straightforward kind of parser to hand-build is a recursive-descent parser. The basic premise is that you have a group of cooperating mutually-recursive functions (or methods), each of which ...
Michael Homer's user avatar
  • 13k
11 votes
Accepted

How are C++ style references implemented behind the scenes? Could they be implemented without pointers?

From an implementation perspective, there is one very important difference between a pointer and a reference in C++: references cannot be null. This is undefined behaviour: ...
Pseudonym's user avatar
  • 4,726
11 votes
Accepted

How to test a compiler/interpreter?

I'm going to talk about compilers, although some of this advice also applies to interpreters. Given a test program, and a potentially buggy compiler, there are essentially four questions that you can ...
Pseudonym's user avatar
  • 4,726
10 votes
Accepted

Is it possible to bootstrap an interpreted language?

It is obviously impossible for a interpreter to only be able to be interpreted by itself, as that would require a infinite chain of interpreters. Each one would slow down the entire system and require ...
mousetail's user avatar
  • 8,359
10 votes

Why does Python ignore type hints?

Python's typing model is intended for outside checkers to check python code. Pretty much any expression can go in a type hint: x: print("hi") = 1 print(x) ...
blueberry's user avatar
  • 2,465
10 votes
Accepted

What are the pros/cons of a tree-based interpreter vs a bytecode-VM-based interpreter?

The main reason to write a tree-walking interpreter is that it's easier. If you compile to bytecode and then interpret the bytecode, you are either writing a compiler to an existing bytecode language (...
kaya3's user avatar
  • 19.7k
9 votes

Why was C implemented with a register preservation convention that seems to be far less efficient than its predecessor's?

How registers behave across function calls is part of the calling conventions defined by a particular language implementation. To facilitate cross-implementation and cross-language calls, most ...
Gilles 'SO- stop being evil''s user avatar
9 votes

Is it possible to bootstrap an interpreted language?

It is not possible to create a fully bootstrapped interpreter. However, it is entirely possible to create a bootstrapped compiler that targets some lower language which is then interpreted. For ...
Olive's user avatar
  • 470
9 votes

Why do so many programming languages not have a "built-in" way to do simple math functions?

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 ...
Corbin's user avatar
  • 851
9 votes

Why do so many programming languages not have a "built-in" way to do simple math functions?

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. ...
kaya3's user avatar
  • 19.7k
8 votes

How can I infer the type of an empty literal?

Instead of marking the type as list[<unknown>], give the <unknown> a name in the form of a variable. Say, ...
Silvio Mayolo's user avatar
8 votes

What are the advantages/disadvantages of null-terminated strings vs length-prefixed strings?

Length-prefixed can include capacity This lets you "over-allocate" storage and remember how much you did so: ...
Bbrk24's user avatar
  • 9,067
8 votes
Accepted

How can I reduce the amount of AST duplication in my code?

One strategy I have read about, but not implemented myself, is the "Trees that Grow" pattern: Original paper GHC wiki overview of TTG GHC wiki implementation notes A small example that ...
quiet_laika's user avatar
8 votes

Approaches for implementing weak references

Most of the information in this answer comes from a blog post titled Surprising Weak-Ref Implementations: Swift, Obj-C, C++, Rust, and Vale by Evan Ovadia, the designer of Vale. Objective-C The ...
kaya3's user avatar
  • 19.7k
8 votes
Accepted

Empirically, what are the implementation-complexity and performance implications of "unboxed" primitives?

The main decision you have to make is whether your language will be sufficiently statically typed that you don't need type tags for unboxed primitives at runtime. Java (or rather, JVM bytecode) is an ...
kaya3's user avatar
  • 19.7k
8 votes

How do lexers/parsers distinguish between nested generics and bitshifts?

There is actually no reason to assume that a file is tokenized until the end before parsing begins. There are frameworks allowing you to generate parsers and tokenizers that use tokens streams that ...
feldentm's user avatar
  • 1,831

Only top scored, non community-wiki answers of a minimum length are eligible