The use of ‘=’ for assignment in programming languages comes, not directly from mathematics, but indirectly from the use of mathematics in science and engineering. As an example, consider the formula for kinetic energy, commonly written
𝑚𝑣²
𝐾 = ───
2
Why isn't it written 2K=mv², which expresses the same mathematical equality in a smaller, simpler form? Or any of the other equivalent rearrangements? It's because formulas have a convention, where the LHS is a single term naming the value you want, and the RHS contains the terms for values you have. That is, a formula doesn't just state an equality, it states a method for calculating something. That usage predates programming, and was explicitly copied by early programming languages like For[mula]tran[slator] that were designed for scientific & engineering calculations.Sure, algebra was fine, a(x+y)=ax+ay can go either way; but not ratios and other relationships.
What helped me was was geometry, where you can see it's just a relationship. All the components move together; one part isn't priviledged as the result.
e.g. you enlarge a circle. It doesn't make sense to ask whether the radius made the circumference bigger, or the circumference made the radius bigger.
“The change of subject from “The dog bit the boy” to “the boy was bitten by the dog” is similar to the change of subject in a formula, as for example … In each case, the two sentences state the same relationship, but with different emphasis.” [1]
[1] https://medium.com/q-e-d/that-loser-woman-mathematician-who-...
https://en.wikipedia.org/wiki/Thematic_relation
Does Hacker News have built in LaTeX, or is that just very clever use of Unicode?
But there is a good reason to write it as K=mv^2/2 which has nothing to do with specifying a computation. It is the result of symbolic integration of p=mv with respect to v.
I also ask "why haven't more symbols been introduced to our keyboards? Just !@#$%&*..."
It's strange, esp. when you realize coming up with a new symbol that everyone uses is easier these days than it was 4 centuries ago!
Take an advanced math test and try to type it out. Being in no sense historically limited by typewriters/keyboards, you might be surprised at the complexity of the symbols.
This is simply not true.
Because you want to find the value of K, which means that if it was expressed thusly, you'll still need to divide by 2 to get to the desired result.
> There is a standard procedure for multiplication, which yields for the inputs 27 and 37 the result 999. What can we say about that? A first attempt is to say that we have an equality "27 x 37 = 999". This equality makes sense in the mainstream of mathematics by saying that the two sides denote the same integer [...] but it misses the essential point: There is a finite computation process which shows that the denotations are equal.
> [...] if the two things we have were the same then we would never feel the need to state their equality. Concretely we ask a question, 27 x 37, and get an answer, 999. The two expressions have different senses and we must do something (make a proof or a calculation, or at least look in an encyclopedia) to show that these two senses have the same denotation.
Typically, the objects related by equality can be thought to have the same meaning with respect to extension and different meanings with respect to intension. Further, the difference in intension reveals something of the computational content of the extensional object being referred to.
Further topics to explore: the BHK interpretation of intuitionistic proof and the univalence axiom in homotopy type theory. Both of these topics give one some insight on the relationship between the computational content of mathematical objects and how this content pertains to the question of whether two objects are “the same.”
Finally, I did skim the article itself and found it lacking. The author seems to be aware of the fact that there are surprising, highly non-trivial properties of the (seemingly trivial) notion of equality in mathematics. And also to be aware of the fact that the use of ‘=‘ in CS contexts isn’t some sort of abuse of notation. But there seems to be very little of interest here beyond some circumstantial verification of these two general (and well-known) facts about equality in the mathematical and computational contexts.
Thanks! For the interested, Girard's book focuses on the Curry-Howard isomorphism, another great result linking computer programs (actually, the typed lambda-calculus) to mathematical proofs.
f(x) = 2x + 3
Might be translate into something like, For all x in the domain of f, f(x) = 2x + 3
Or maybe further, f = { (x, y) in Cartesian product of domain and codomain | y = 2x + 3 }
Where equality is, I think, strictly defined here as set equality.The articles other point in this example is that we might way “when x = 2, f(x) = 7.” Claiming that x is used both as an indeterminate value and a concrete value. Again, I think the ambiguity is resolved when translate using the correct quantifies, something like “for all x in the domain of f, if x = 2, then f(x) = 7.”
Or perhaps you might claim, “there exists an x in the domain of f such that f(x) = 7.” The important point being that the function f is formally NOT the formula f(x) = 2x + 3, but a particular set of ordered pairs, of which you can make formal statements about in first order logic.
Another example used was
A = {n^2 | n = 1, 2, ... 100}
But again this is just “syntactic sugar” that a reader would translate into perhaps A = { n^2 | n in {1, 2, ..., 100}}For example, if we consider the atomic formula x = 5+y, then we may mean the identity ∀x∀y (x = 5+y), where all variables are universally quantified.
Or we may mean ∃x∃y (x = 5+y), where the variables are existentially quantified. To determine whether this holds, we can search for a solution given by a substitution that makes the terms equal modulo some theory E we associate with =. If E is empty, then this corresponds to syntactic unification.
Confusingly, in the literature, sometimes "equation" is used for both, and an entire subthread in this discussion is due to this issue.
When one is asked to "solve for x" etc., then one answers whether there is any solution, thus solving the existentially quantified version. When one means "this identity holds", then one states the universally quantified sentence.
Since assignment is about twice as frequent as equality testing in typical programs, it’s appropriate that the operator be half as long.
Of course, that's wrong. Trying to make it easier to type, a bigger usability problem is created, assigning counterintuitive symbols to functionality that most people would not associate to them.
So the problem is not what = means in maths, it's what it means for people learning a language. Anyway, smadge is right: most of the uses in maths are of the kind "a little imprecission saves tons of explanation". In other words: that's not a question of what = is, but a question of how we use it to get things done.
Oh and then there is the "I'm used to it so it must not be so bad" crowd and the rationalization ensues.
However, I think that using this as a justification for programming languages' use of the equals sign for assignment (whether or not it needs any justification at all) I think is a moot point because mathematics is more expository, and isnt always strictly rigorous as long as its clear that everything is well defined and correct in the end (although there is expressiveness in the formalities as well).
> Rather than precisely say, f(2) = 7, we say that for x=2, f(x) = 7. So x is simultaneously an indeterminate input and a concrete value
This seems like a perfectly by-the-book piece of second-order logic with two equality predicates.
i.e., the statement asserts that if you look at the space of all possible values for x, then for each value where the predicate "x = 2" holds, the other predicate "f(x) = 7" will also hold. It happens there is only a single value that will satisfy "x = 2", but that's not the equality's problem.
So both = signs really are equality here.
Computer languages make no exception: they are nothing else than formalisms to express computations. As for every other formalism, the meaning of signs is chosen to be what appears most comfortable in that context by the formalism designer. The statement "x = x+1" has very different interpretations depending on whether you consider it written in C or in standard polynomial equation theory; but in both cases there is a well known meaning for it. In exactly the same way the word "case" has different meaning depending on whether your are reading in English or in Italian.
Oh, and the wonderful notation for integrals, ∫ 2x dx = x² + C
∫ f(x) dx = set of solutions of diff. eq. g'(x) = f(x)
Of course, writing
∫ 2x dx = { x² + C | C ∊ R }
grows old pretty fast, so we drop a couple of characters here and there, but it's pretty consistent with set-builder.
Of course, this only goes to show the article's point that what "=" means here requires a lot of context.
3 * 3 ≡ 1 (mod 4)
but in the next year Algebra course about groups and crazy algebraic structures the notation in the group Z_4 is just 3 * 3 = 1
and everyone understand that you are working in Z_4 (and the * and = symbols are "overloaded" (but no one call them "overloaded")).I should also add that, as generally presented in higher level math, modular arithmetic actually does use literal equality. The abuse is in the numbers.
That is to say, when we write "9" in modular arithmetic, we mean the set of all numbers congruent to 9. In this case in "9=1 mod 4" the equality is literal because the set of numbers congruent to 9 is literally the same set as the set of numbers congruent to 1.
Source that both are in use: https://math.stackexchange.com/questions/196081/the-right-wa...
I think the author hints toward a good point: there is no use arguing over the meaning of "=" in a general sense, because the meaning is contextual.
I think this whole discussion is merely indicative of inexperience on the part of computer scientists attempting to navigate mathematics.
Before Knuth popularized Big O notation in CS and started the field of analysis of algorithms, already in 1958 N. G. de Bruijn wrote an entire book on Asymptotic Methods in Analysis (not CS): see a few of its leading pages here: https://shreevatsa.wordpress.com/2014/03/13/big-o-notation-a...
And the notation was already being used by Bachmann in 1894 and Landau by 1909 in analytic number theory, well before computers. It was perfectly commonplace to use big-O notation with the equals sign very quickly: see e.g. this paper by Hardy and Littlewood (https://projecteuclid.org/download/pdf_1/euclid.acta/1485887...) from 1914, well before even Turing machines or lambda calculus were formulated, let alone actual computers or analysis of algorithms.
For instance we might say:
sin(x) = x -x^3/6 + x^5/120 + O(x^7)
To indicate that the terms we did not write are in O(x^7). Also note that, in this case, we are actually looking at big-O as x->0.In model theory you don't require your models to have an equality operator, they have one simply by being logical constructs.
Then again mathematicians use quotient spaces so transparently that you might as well consider:
5 = 1 (mod 4)
as 'overloading the equality operator' even though the technical definition implies that those 5 and 1 are different from the 5 and 1 in the set of natural numbers, and in Z/4Z the symbols 1 and 5 refer to the same object.
S[ x ↦ V ]
indicates that the new state is equal to old state S, but with variable x now bound to value V.
Math symbols and expressions are inconsistent just like regular languages. But, unlike math, other languages don't claim to be consistent.
It's not surprising that John von Neumann said "in mathematics you don't understand things. You just get used to them." - I've never heard a software developer say this about coding.
For example, I did not enjoy integrals at school because of the 'dx' at the end which means 'with respect to x' but which actually looks like a multiplication (* d * x).
I think that the reason why I never got deep into math is because the language of math is too inconsistent and has too many logical shortcuts and I can't operate in such environment.
(even in my pure math classes, I sometimes imagined that the variables had units, to help find mistakes).
But your point is well taken about the consistency of math notation. Math spent most of its history being scribbled by hand and read by humans. It got the job done. And it was not uncommon to invent a new notation on the fly to replace an abstraction with a single symbol. That's the precursor to the subroutine.
The need for perfect formality of notation is a new thing, brought on by the computer age. This may illustrate the point that programming is not "just math," and math is not a form of programming.
This is sarcasm, right? We say this all the time about legacy spaghetti code or excessively clever magic our languages or (closest to von Neumann's statement, perhaps) the mountain of APIs and libraries and OS we use..
The notation "x = x + 1" is awful because at lhs x denotes a reference to an integer while at rhs x denotes the value hold by the reference. If you know C, it is similar to the difference between an integer pointer *x and an integer x. As an illustration, here are two programs that are doing the same thing, one in C and one in Haskell.
#include <stdio.h>
int main() {
int x = 0;
x = x + 1;
printf("%d\n", x);
return 0;
}
import Data.IORef
main :: IO ()
main = do
xref <- newIORef 0
x1 <- readIORef xref
writeIORef xref (x1 + 1)
x2 <- readIORef xref
print x2You don't say "angles are equal" - you say they are congruent. It's their measures that are "equal".
Although congruency implies measure equality, it doesn't really mean that, but that the shapes are the same (can be rotated/translated to coincide).
Two triangles on a page are congruent, because they have different position. The three corners of an eauikao trisne are congruent, because their corner+angles are equal. If you take angle to mean corner, you say congruent. If you aren't also talking so about their position, you say equal.
In math you can slice things every which way, so it's impossible to use the different words for every different concept, so you have to establish a context
Equal vs congruent (and equal vs equivalent, which are also synonymous in math) is a crutch for beginners who are over reliant on their informal intuition.
> If mutation is so great, why do mathematicians use recursion so much? Huh? Huh?
> Well, I’ve got two counterpoints. The first is that the goal here is to reason about the sequence, not to describe it in a way that can be efficiently carried out by a computer.
Most high level languages try to avoid making the programmer describe the most efficient way to handle variables. The idea is to describe your algorithms and how they connect and allow the compiler (or interpreter) to figure out how to use registers etc to implement it. Of course that ideal breaks down sometimes but most high level programmers don't normally need to stress the low level details too much.
> My second point is that mathematical notation is so flexible and adaptable that it doesn’t need mutation the same way programming languages need it. In mathematics we have no stack overflows, no register limits or page swaps, no limitations on variable names or memory allocation, our brains do the continuation passing for us, and we can rewrite history ad hoc and pile on abstractions as needed to achieve a particular goal.
It's true that there's a limit to abstractions even the highest level languages can make if they want to remain general purpose. However I think languages can handle immutable variables as a default.
That's not to say I agree that programming should always follow mathematical notation. But I also don't think it's a bad ideal in many cases.
Even though there's a correspondence, there's always going to be a difference between writing a program so that you can actually run it and writing proofs, where you don't, and ridiculously inefficient algorithms don't matter at all, so long as they don't diverge.
>"You… do realize that the type system is meant to constrain values, right?”
>“No,” you inform him, matter-of-factly. “No, that doesn’t sound right.”
It's true, you can't rely on tail call optimizations on every language. But practically all modern compilers for imperative languages transform your code into SSA form[1] in one of their intermediate stages, so the code:
int x = 1
x = x + 1
will invariably be transformed into: int x0 = 1
int x1 = x0 + 1
in one of the intermediate stages - before applying further optimizations and finally converting it to stack-based bytecode or register-based machine code.This means that mutating a variable, at least when dealing with local primitive values, is equivalent to assigning the value to a new variable.
Even in other cases, in-place mutation is not necessarily more efficient than copying and modifying values. For multi-threaded code, mutation often requires relying on synchronization which can be more expensive than copying around data.
> Simply stated, the goals of mathematics and programming are quite differently aligned. The former is about understanding a thing, and the latter is more often about describing a concrete process under threat of limited resources.
In the current day and age, if a programmer would wants to write the most efficient code, they need to understand a lot about their multi-stage optimizing compiler, Out-of-order CPUs, OS threads and so on - and they would still need to benchmark their implementation against others. It is not clear anymore that mutation is always faster.
I think that in 99% of the cases, clear, safe and maintainable code trump the micro-optimizations that may (and often may not) be gained from using mutable data. Immutable data is generally easier to reason about, always safer from data races and other bugs, and - in most languages languages - more maintainable.
The age of limited resources and straightforward compilers is long over, but it left mutable variables as its heritage. I'd argue they're still common not because they are necessary to deal with hardware limitations, but just because generations of programmers have gotten so used to them, it's hard to give up on them.
[1] https://en.wikipedia.org/wiki/Static_single_assignment_form
> Huh? Huh?
The deal here is surely that induction and other recursive approaches are conducive to being reasoned about in traditional mathematical contexts (e.g. taking a walk). Mutation is impossible to keep track of, mentally. Though others' mileage will vary on that.
Let me confess that I’ve not read every answer. But the ones that I did read were all very concerned with “squaring” etc.
The simplest answer — and I think the reason many people have difficulty with both arithmetic and especially algebra — is that you need to deeply internalize just what the “=” sign symbolizes and asserts: that there is the very same number on each side.
In other words don’t be distracted by the symbols and operations. One way to think about this is that “a number is all the ways you can make it” (i.e. it can be thought of as “processes” (an infinite number of them) as well as a “value”).
This means whatever you can do to any number can be done on both sides of the “=” because there is just the same number underneath the gobblydegook on both sides.
This is what “=” actually means. And it’s why algebra is actually quite easy rather than mysterious or difficult. [0]
x + 3 = 1
Typically we write that the solution is "x = –2". This to me is the most abusive form of usage for "=" in mathematics. The solution to the equation is –2. The solution to the equation x = –2 is also –2.
Solving the equation x = –2 is very easy. We can solve it just by looking at the equation. What we are really doing when solving an equation is transforming the original equation into a simpler equation with the same solution set. Tt gets tedious to write this all out so we just say things like "the solution is x = -2" when we've transformed the original equation to x = –2. This is weird because x is not the number -2. x is a variable that can assume a myriad of values. The only value of x that solves the equation is –2.
As the article states the abuse of the = sign in mathematics is rampant. We do it mostly without realizing it. In this sense mathematical language mimics human languages. All human languages are prone to abuse of rules and to shifting with the times.
The notation in mathematics, while much more precise than spoken human languages, is abused frequently and the purpose is to make things cognitively easier. The ancient Greeks didn't have symbols for numbers and in their mathematics they wrote everything out in Greek. This makes it very hard to do tedious calculations. Using symbols in lieu of writing out all the minutia makes doing math easier provided you learn the contextual meaning of the symbols. Over the centuries symbols have been introduced as a shorthand for complex ideas/objects/operations. If you want everything precisely stated then reading Principia Mathematica ought to cure you of this desire. Mathematics is written by humans for humans.
Code is written by humans for computers and hence the notation needs to be rigorously defined in the language you are using and why your code needs to be commented.
I think variables in equations are not meant to express the existence of variance within an equation, but a sense of context-dependency of the value of x. At least, IMO.
x+3 = 1
is asking the question, “what value for x makes x+3 the number 1?”
The polynomial x+3 is defined for all values in R, the base ring you are working in. We are trying to find the elements of R for which x+3 is the element 1.
x y + 2 = 0
has infinitely many solutions. One of them is (1, -2).
I disagree, though I think it's fine to think of a bare “-2” as a solution when you have a single variable, when you deal with equations or systems of multiple variables it breaks down. Sure, you can think of the solution in terms of untagged tuples when the variables have conventional orderings, but that just highlights that the lack of tagging the variable with the value is a shorthand, not the “true” form of the solution. And it's as much a shorthand in the one-variable case.
In two variables we get a map from R^2 to R^2and solutions are ordered pairs. By definition of an element of a polynomial ring over R the variables are ordered.
That is not overloading "=" at all. It is overloading the word "solution".
What your teacher probably told you is:
"x+3=1 is equivalent to x=-2 by .... Hence, the solution of x+3=1 is the same the solution of x=-2 (which is -2 in both cases). Since the solution of x=-2 is so obvious, we also say the solution is x=-2 to mean that it is the same solution as of the equation x=-2."
Same difference as in "Q:Would you like a large coffee or a small coffee? A: Large " The correct answers should only be either phrase "A large coffee" or "a small coffee", but the answer was an adjective.
I’m a mathematician so it’s something my teacher said as such but something that I noticed consciously when I started doing some programming.
No it can’t. x in this case is a bound variable. It’s not that it just so happens to take on -2, but that it is already bounded to -2 to make the statement true.
It really says: There exists some x in Z such that x + 3 = 1. What is that x, or what is a proof of the statement? The answer is in the form of a logical implication.
x is actually just, in the language of computer science, syntactic sugar. In reality x+3 is really the infinite tuple
(3, 1, 0, 0, .....)
=
eq
eql
equal
equalp
string=
...
Because equivalence mean many things in both the mathematical and programming world.But think going deeper into this is quite fun
Your post goes to the point at the heart of philsophical number theory.
What does equality mean ?
Yup – you got functinal equivalence, isomorphism, and temporary assignment of values.
But I think you could prove – that all these types of equality – are “instances” of “different implementations” of “equivalence.
They are no more equivalent than 1 = 1 is equivalent.
I.e. 1 = 1 means I think we can define a bijective “counting function” that proves there’s the “same number” of “elemetns” in the “sets”
I think (not sure) – if you define – counting fucntion / same number / elements / sets differently – you get the differing definitions of equivalence you enumerate.
The interesting thing for me is that 1 = 1 is defined clear in 4 of peano’s axioms
https://en.wikipedia.org/wiki/Peano_axioms#Formulation
And you could mentally – try to develop different (and potentially) – more powerful notions of “equivalence” – with differing axioms
A final point… the prevalence of several “similar” concepts of equivalence in computer science – may point to an underlying “platonic idea” of equivalence – that either exists dormant in the world awaiting for us to discover it; or is a useful “technologocial” construct – that has accelerated “progress”
Also, if I were you, I would always look up introductory textbooks before trying to read math literature. The example you gave is conditional probability; any textbook on probability theory would cover it.
- John Baez ( http://math.ucr.edu/home/baez/week147.html )
--
\
/
--
0 < i < n
Ass opposed to n
--
\
/
--
i = 1 ---
\
/
---
i∈[1,n]'=', like number, means that concept, regardless of instantiation.
Beyond that note, I don't see the value in listing all the ways you could interpret notation.
Maybe you would also find it entertaining to list all the ways a program can interpret a binary string?
i_1 =/= i_2.
As xg15 noted, it's perfectly fine to say (x=2) => (x + 3 = 5). The problem the first example really addresses is that in mathematics, the namespaces are loosely defined, but in programming they aren't. 'i' can mean several things at once, and it doesn't really matter because those things never really interact in the same context. In programming, you need to specify the name 'i' every time you want to reference it, so it's important that you have a stricter namespace rule.
After I understood what it really meant, I wondered why they didn’t use some other symbol to capture this semantic. Say something like x <- x+1 ; Which implies assignment rather than equality - That way this would be unambiguous and I feel is more clear. I now guess the choice of using ‘=‘ was probably an attempt at making a (compromised) choice given the limited symbols that were available back when High level languages were first written?
https://www.hillelwayne.com/post/equals-as-assignment/
The summary is that C used it because assignment was a lot more common than equality checking, and back then, typing fewer characters was a big deal.
https://stackoverflow.com/questions/1741820/what-are-the-dif...
Edit: Misunderstood, thought you were talking about math, not programming languages.
https://en.wikipedia.org/wiki/Assignment_(computer_science)#...
> A = { n^2 : n = 1, 2, …, 100 }
> In Python, or interpreting the expression literally, the value of n would be a tuple, producing a type error. (In Javascript, it produces 2.[link] How could it be Javascript if it didn’t?)
That linked JS code uses ^, which is xor, not pow. Math.pow([], 2) = NaN. Or maybe that was the joke and it flew completely over my head.
See, for example, https://www.destroyallsoftware.com/talks/wat
console.log([1,2,3,4,5,6,7] ^ 2);
This produces 2 because ^ is the bitwise XOR operator in Javascript. Arrays are not numeric types, so they appear to be coerced to 0 for this comparison. In short, they are effectively logging "0 XOR 2", which is 2.