
Why Does “=” Mean Assignment? - panic
https://www.hillelwayne.com/post/equals-as-assignment/
======
todd8
As the article points out, the big first programming languages, FORTRAN,
COBOL, LISP, and Algol each had their own way of doing variable assignment.
FORTRAN used "=" and Algol used ":=" the other two languages used commands or
functions to set or bind the values of variables.

In the mid 60's, when I started programming, most programs had to be
keypunched. (There was paper tape entry and Dartmouth's new timesharing system
using BASIC, but these weren't in very widespread use.) Until 1964, the
keypunch machine in use (IBM 026) had a very limited character set. This is
the reason that FORTRAN, COLBOL, and LISP programs were written in upper case.
Even the fastest "super" computer of the time, the CDC 6600, was limited to
6-bit characters and didn't have lower case letters.

Naturally, symbols like "←" or "⇐" weren't available, but even the characters
":" and "<" were not on the 026 keypunch keyboard and so ":=" or "<-" were
much harder to punch on a card.

These early hardware limitations influenced the design of the early languages,
and the early programmers all became accustomed to using "=" (or rarely ":="
or SET) as assignment even though "⇐" might have been more logical. The
designers of subsequent programming languages were themselves programmers of
earlier languages so most simply continued the tradition.

~~~
mygo
I feel like this is the best answer. People have to work with what they have.
Much in the same way that SNES games look the way that do, even though the
designers back then were just as smart and talented as the ones today. That’s
simply what they could do with the medium at the time.

The limitations define the style. And then dogma perpetuates it, as the new
generation continues to live with the results of once-great but now outdated
thinking.

~~~
mygo
*The limitations define the style. And then dogma perpetuates it, as the new generation continues to live with the once-great but now outdated results of someone else's thinking.

------
rdtsc
Another interesting way to think about it is as "match". That is try to match
the stuff on the right with the stuff on the left.

Take Erlang for example:

    
    
        1> X = 1.
        1
        2> X = 2.
        ** exception error: no match of right hand side value 2
    

Notice variables are immutable (not just values themselves). Once X becomes 1,
it can only match with 1 after that. You might think this is silly or
annoying, why not just allow reassignment and instead have to sprinkle X1, X2
everywhere. But it turns out is can be nice because it makes state updates
very explicit. In complicated applications that helps understand what is
happening. And it behaves like you'd expect in math, in the sense that X = X +
1 doesn't make sense here either:

    
    
        1> X = 1.
        1
        2> X = X + 1.
        ** exception error: no match of right hand side value 2
        3>    
    

It does pattern matching very well too, that is, it matches based on the shape
of data:

    
    
        1> {X,Y} = {1,2}.
        {1,2}
        2> X.
        1
        3> Y.
        2
        4>
    

In other languages we might say we have assignment and destructuring but here
it is rather simple it's just pattern matching.

~~~
bogomipz
>"In other languages we might say we have assignment and destructuring ..."

I'm not familiar with this term "destructuring." Can you elaborate on the
concept? Might you have an example of a destructure operation and a language
where its's used?

~~~
ajuc
[https://clojure.org/guides/destructuring](https://clojure.org/guides/destructuring)

Basically it means that you can assign several variables at once, by
asssigning a complex value to an aproprietly structured literal with variables
as placeholders.

In pseudojavascript, let's say you got this from some API:

    
    
        var someList = [1, 2, 3, 4];
        var someMap = { name: "John Smith",
                        age: 20,
                        cars: [{ id: "AAA-1111", model: "Ford T"},
                               { id: "AAA-1112", model: "Mercedes Benz"}] }
    

And you want to extract useful data for your code quickly. In languages with
destructuring you can do sth like this:

    
    
        var [x, y & rest] = someList; //x==1, y==2, rest == [3, 4]
        var { "name": name,
              "age": age,
              "cars": [ {"id": firstCarId, "model": firstCarModel}
                      & restOfTheCars ]
            } = someMap;
    

And the language will put the correct values in your variables name, age,
firstCarId, firstCarModl, restOfTheCars.

~~~
OvermindDL1
Javascript itself supports destructuing fine, here's some javascript straight
from the firefox console:

    
    
        > let a = [1,2,3]
        undefined
        > [x,y,z] = a
        Array(3) [ 1, 2, 3 ]
        > x
        1
        > y
        2
        > z
        3

------
Stranger43
I think they are forgetting that a lot of languages take que's from old math
textbooks where you would see function definitions written as "f(x) = nx + b"
or "y = nx + b" and constant assignment with a "c = <number>" notation.

if you want to calculate the output of a function into a data table(which is
what early computers were often doing) iterating a variable x over a f(x) = xn
+ b(with n and b being fixed constants) is exactly how you would do it on
paper so it's probably a case of computers emulating applied math rather then
simply being pure theory machines.

~~~
rocqua
This works for initialization, but not for reassignment. Most notably, it is
absurd for statements like x = x + 1. Meanwhile, such self-referential updates
are very common in imperative programming, so anyone designing the language
would come across this.

~~~
vlasev
You have something similar in mathematics. Recurrence relations. Since we are
dealing with a sort of time difference inside a computer, something like "x =
x + 1" can be interpreted as "the value of x at the next time unit is the
value of x at the previous time unit plus one". That is "x[n+1] = x[n] + 1"
and this is a recurrence relation. My guess is that early programmers were
deeply aware of this time difference, so "x = x + 1" made perfect sense.

~~~
jcranberry
What you have there is a sequence. Recursively defined or not, taking the
indices out of a sequence takes away the only thing that makes it a sequence
(the mapping from the natural numbers) and would be a horrible abuse of
notation.

I think language designers were certainly consciously aware that they were
designing something well defined, and chose to use this kind of syntax because
its simpler, rather than an implicit mapping to the natural numbers via
something like CPU cycles.

~~~
rocqua
There is a really simple mapping between recurrent sequences and functions.
Simply, given a function $f: A -> A$ that is, a function that outputs from the
set it gets input from.

We then have the sequence $x_n+1 = f(x_n)$. Often, when dealing with
incremental algorithms, the notation x' = f(x) is used. Here x' (pronounced x
prime) stands for "the next value of x". It's a nice balance between the
correctness of using indices and the conciseness of leaving them out.

Going to a higher level, the sequence x' = f(x) is essentially trying to find
a fixed point of the function f. To look at this in an actual for or while
loop, you need to consider the stopping condition of the loop as part of the
function.

------
Itaxpica
A coworker of mine once referred to := as the 'Zoidberg operator', and the
name has stuck with me since.

~~~
bwldrbst
How about :≡ ?

~~~
chrisan
thats the logically equivalent zoidberg operator

------
open-source-ux
Here's what Niklaus Wirth (Pascal, Modula-2, Oberon) said about using the
equal sign for assignment:

> A notorious example for a bad idea was the choice of the equal sign to
> denote assignment. It goes back to Fortran in 1957 and has blindly been
> copied by armies of language designers. Why is it a bad idea? Because it
> overthrows a century old tradition to let “=” denote a comparison for
> equality, a predicate which is either true or false. But Fortran made it to
> mean assignment, the enforcing of equality. In this case, the operands are
> on unequal footing: The left operand (a variable) is to be made equal to the
> right operand (an expression). x = y does not mean the same thing as y = x.
> Algol corrected this mistake by the simple solution: Let assignment be
> denoted by “:=”.

> Perhaps this may appear as nitpicking to programmers who got used to the
> equal sign meaning assignment. But mixing up assignment and comparison is a
> truly bad idea, because it requires that another symbol be used for what
> traditionally was expressed by the equal sign. Comparison for equality
> became denoted by the two characters “==” (first in C). This is a
> consequence of the ugly kind, and it gave rise to similar bad ideas using
> “++”, “--“, “&&” etc.

From _Good ideas, through the Looking Glass_ by N. Wirth:

[https://www.semanticscholar.org/paper/Good-
Ideas%2C-through-...](https://www.semanticscholar.org/paper/Good-
Ideas%2C-through-the-Looking-Glass-
Wirth/10bddc49b85196aaa6715dd46843d9dcffa38358)

~~~
AnimalMuppet
At one point in my career, I was afflicted with a Wirth-designed language. His
opinion on what constitutes good language design does not carry much weight
with me. In particular, I can tell you that the extra typing of Pascal over C
_really does matter_ over a couple of years. And that := for assignment is a
major pain when your left pinky finger is out of action for weeks, and you
still need to hit shift _for every assignment_.

But then we get to this line:

> Because it overthrows a century old tradition to let “=” denote a comparison
> for equality

In what sense is "=" for comparison a century old? Hasn't it been used for
"things that are equal" for multiple centuries? If so, and if that's distinct
from "for comparison", then isn't for comparison _also_ a new, non-standard
use?

Does anyone understand what he's on about in this quote?

~~~
gowld
In math, "=" is an equivalence relation.

------
slededit
The '=' sign is used because after that statement the variable will indeed
have equality with the r-value.

Coincidentally in async languages like Verilog there is a another assignment
operator '<=' which means that the variable won't take the new value until the
next clock cycle (or more explicitly the next evaluation of the process
block). '=' exists also and has the same meaning as with traditional
languages.

~~~
paulddraper
By that logic,

    
    
        a <= 1
    

Should set a to the minimum of a and 1. I.e. after that statement the variable
will indeed be less than or equal to the RHS.

~~~
slededit
Languages borrowing the syntax don't need to follow its logical consistency. I
just thought it was an interesting anecdote.

------
bhaak
> Since assignment is about twice as frequent as equality testing in typical
> programs, it’s appropriate that the operator be half as long.

Ken Thompson on why '=' is assignment and '==' the equality check.

It's this kind of mindset that puts me off Go. But I can totally see that many
who want a better C getting into Go exactly for reasons like this.

~~~
mikekchar
I'm not sure what you find disquieting about the idea. "More frequently used
operators should be less verbose" seems reasonable to me. What I find a bit
strange about Go is that if they have that mindset then it's still a fairly
verbose language, syntactically -- at least compared to some other modern
languages. It seems to hang on to the familiarity of C syntax with a few
optimisations. Which, of course, is not necessarily a bad thing at all. It's
just not doing everything it can to reduce verbosity.

~~~
bhaak
> "More frequently used operators should be less verbose" seems reasonable to
> me.

Syntax that looks pretty in isolation is a poor design guideline for
programming language design. It ignores the problems of writing and debugging
this code. I don't know how many bugs went unnoticed because of the "if (a =
b)" mistake but it certainly weren't few. Sure, nowadays the compiler warns
you about that but that took surprisingly long to be implemented.

The argument for saving a few keystrokes for potential longer debugging
sessions is not a good argument. Code is much more often read than it is
written.

But I didn't criticize Go's verbosity (after all, they "fixed" the assignment
thin) but the mindset of doing or not doing things for specific reasons that
look quite backwards for today (or let me be frank, just plain stupid) but the
community then fights with vigorously for this. There are examples for that in
the design of the language but the most egregious example of this is the
package manager. This went from "we don't needs this" over "do it in this
problematic way" over "let's do it like anybody else" to now "no, we are
special, we need to do it completely differently".

IMO, Go would have been a fantastic language to have in the 90s. But looking
at it from today's perspective, it looks outdated in many places. But compared
to C which is a language of the 70s it is still great and therefore I
understand its appeal for programmers who haven't found another language to
replace C with (going from my own experience, most programmers have replaced C
with multiple languages instead of just one).

------
abakus
The length of symbols should roughly be negatively correlated with its
frequency.

Since in procedural language, assignment is a much more common operation than
equality check, it is reasonable to favor "=" over ":=" or even "<-".

~~~
roselan
What does prevent : to become the assignment operator of a language? It's
short, and quite "explicit".

x: 2

~~~
Izkata
The Rebol family of languages works like that.

~~~
9214
Except that it doesn't. ":" in "x:" is not an assignment operator and "x" is
not a variable.

~~~
Izkata
Yes yes, it's a set-word! type in the "do" dialect. That's not how it's
learned when first starting, though, and not usually the thing you're thinking
about when using it moment-to-moment.

------
cosmotron
I actually rationalized the '=' symbol in assignment into the following
statement, "Let 'left hand side' be equal to 'right hand side'". Using this
wording resolves some dissonance around its overloaded usage.

~~~
amyjess
Ditto.

Fun fact: various dialects of BASIC let you optionally put LET before your
assignment statements. So the following are equivalent:

    
    
        X = 10
        LET X = 10

~~~
joezydeco
Wait...LET was optional? Auigh! Whole months of my childhood, wasted!

~~~
Doctor_Fegg
Depends on the dialect. It was mandatory on the Sinclair BASICs, for example
(ZX81/ZX Spectrum), but optional on the Amstrad (Locomotive/Mallard) and BBC
BASICs. A quick search suggests it was optional as early as "MicroSoft"'s
Altair BASIC:
[http://swtpc.com/mholley/Altair/BasicLanguage.pdf](http://swtpc.com/mholley/Altair/BasicLanguage.pdf)

As someone who learned first on a ZX81, I'd always assumed that "LET X=5" was
the canonical form, and that "X=5" for assignment was just a shortening for
convenience.

~~~
jameshart
Likewise - but of course in Sinclair BASIC it was mandatory because _every_
command had to begin with a keyword - a fact enforced by the fact that the
cursor started out as a flashing [K], and every key on the keyboard was mapped
to directly enter a keyword in that mode. LET was on the 'L' key. You
literally couldn't type "a = 1" into a Spectrum/ZX81 - you couldn't type an
'a' unless you were at an [L] cursor prompt, which would only appear after you
had chosen a keyword. Typing an 'a' at a [K] cursor would get you the keyword
NEW.

I wonder if you, like me, were also completely thrown when you first
encountered a programming language where you didn't also have to enter line
numbers...

~~~
feintruled
> I wonder if you, like me, were also completely thrown when you first
> encountered a programming language where you didn't also have to enter line
> numbers...

Haha, yes, totally! For me this was AMOS on the Amiga (a Basic variant). I was
so thrown I started by using them anyway as they were supported by the
interpreter - it just treated them as labels.

I soon stopped though when I discovered it didn't reorder based on number, so
you ended up with

    
    
      10 print "world"
      5 print "hello"
      20 goto 5

------
russellbeattie
I've been programming professionally for 25 years using mostly C inspired
languages, and I will still regularly write "if(foo = bar)" on a daily basis
and not notice until there's an error. It's easily the most common syntax
error I write, followed closely by using commas in my for-loop as apparently
it looks like a function to my fingers: "for(x=0, x<10, x++)"

~~~
jandrese
Don't compilers warn about assignment inside of conditionals now?

~~~
gumby
In C++17 not only can you do assignment in the conditional, you can declare
new variables which have the scope of the then and else clauses.

But yes, most compilers will catch this case.

~~~
gowld
The compiler warns unless you add an extra () around the assignment to signal
that you mean it.

------
DubiousPusher
My first programming teacher insisted we call the single = sign the 'gets'
operator. So

int x = 10 int y = x

would read in English as x gets 10, y gets x.

Shortly after that class I took a break from any coding. When I went to
another school I saw Softmore and Junior level programmers still struggling
with this. I retained the habit of using 'gets'and never had a problem with
this.

~~~
rocqua
I've heard the same but with 'becomes' rather than 'gets'. I think becomes
works better for people with a mathematical background, where the concept of
variables is totally natural. For people without this, 'gets' might be better
because it helps anthropomorphize the variable. The coder 'gives' X a value to
hold.

~~~
DubiousPusher
If you're speed reading some code 'becomes' is a bit of mouthful.

~~~
rhaps0dy
Do you mouth the name of operators when you read code? Like most people I do
make the words sound in my head when reading text but only the variable names
make sounds when reading code.

~~~
DubiousPusher
I'm a bit of a mutterer but it depends on my mood I think.

------
reaperducer
You'll have to pry my BCPL heffalumps out of my cold, dead hands.

    
    
      The operator " = >" (pronounced "heffalump") is 
      convenient for referencing structures that are 
      accessed indirectly. The expression 
      a=>s.x is equivalent to the expression (@a)»s.x.
    

Source:
[https://archive.org/stream/bitsavers_xeroxaltobualSep79_5187...](https://archive.org/stream/bitsavers_xeroxaltobualSep79_5187659/BCPL_Reference_Manual_Sep79_djvu.txt)

------
ken
I don't understand the LISP line at all. I would have said "LET", "SET", and
"EQUAL" (since it's talking about numbers). Is there something I'm missing?

EDIT: It's since been changed to "let", "set", "equal" (but still lower-case).

~~~
EdwardCoffin
I don't understand it either. I suspect the author does not know Lisp, and
badly misunderstood an explanation from someone who does.

I think that Lisp doesn't even fit well into that table, since putting LET in
the first column would implicitly bring in declaration as well, much of the
time SET in the second column would be misleading since mutation is so often
done implicitly by a looping construct like DO, DOLIST, DOTIMES or whatever
(no SET in sight), and there are all sorts of equality tests one could use.

Edit: ok, I see the author has both updated it, and is specifically talking
about Lisp 1.5 which does not have the looping constructs. On the other hand,
it at least has a bunch of alternatives to SET that probably should be listed
as well, like RPLACA, RPLACD, ATTRIB, and so on. I think that even in Lisp 1.5
variables could be declared in different ways to using LET (like rebinding a
variable passed in to a function, so the assignment was in invocation).

~~~
ken
It's not a perfect correspondence, but I think the point is simply to show
that back in the 1950's, there was no consensus yet on how assignment ought to
look.

It just happens that there was no consensus yet on how it should _work_ , yet,
either!

Then again, neither of the last 2 (modern) programming languages I've used
have had FORTRAN/ALGOL-style assignment semantics, so I think the jury's still
out.

------
rootbear
During the public comment period for the original ANSI C standard, we had at
least one request to add ":=" as an alternate assignment operator. We
declined, but I personally would have supported that. The use of = and == is
one of my least favorite bits of C syntax.

~~~
rootbear
These days, I suppose we could add the Unicode character for :=

≔ U+2254 COLON EQUALS

and there is also

⩵ U+2A75 TWO CONSECUTIVE EQUALS SIGNS

if you find typing two = characters fatiguing...

------
cm2187
Another question is why the assignment is from right to left when the natural
direction would rather be left to right, like 2+2 => x to store the value 4 in
x.

I was told once by a math professor that it is a habit inherited because we
use Arabic numbers/maths which were really meant to be read from right to
left. Don’t know if the theory has any merit.

~~~
gowld
English has Subject-verb-object word order, not object-verb-subject. That's
why x is the first word in x = 2+2

~~~
dragonwriter
> English has Subject-verb-object word order, not object-verb-subject

Imperative programming corresponds to the imperative moodin English, where
English normally has verb-object word order with the subject (the entity being
commanded) ommitted. The subject of the command to set the value of _x_ to the
result of the addition of two and two is the computer/runtime running the
code, not the variable _x_ which is the direct object.

English has SVO order for _declarative_ sentences, which correspond to
declarative programmig, which tends to feature definition or binding rather
than mutating assignment.

------
PrimHelios
>A common FP critique of imperative programming goes like this: “How can a = a
+ 1? That’s like saying 1 = 2. Mutable assignment makes no sense.” This is a
notation mismatch: “equals” should mean “equality”, when it really means
“assign”.

I sort of disagree with this. Many functional languages pull heavily from
lambda calculus and other forms of mathematics. In math, "a = a + 1" isn't the
same as "1 = 2". The issue isn't equality, it's that you're trying to rebind a
bound variable, which isn't possible.

In other words, rebinding a bound variable is not the same as "1 = 2".

~~~
kbp
> In math, "a = a + 1" isn't the same as "1 = 2". The issue isn't equality,
> it's that you're trying to rebind a bound variable, which isn't possible.

"=" means equality in math; a = a + 1 is the same as 1 = 2 because if you
subtract a from both sides and add 1 to both sides you get 1 = 2.

Lambda calculus has the concept of binding variables, but it doesn't use "="
for that, it uses application of lambda forms. It's the same idea that's
applied in some variants of Lisp, where LET is a macro such that (let ((x 1)
(y 2)) ...) expands to ((lambda (x y) ...) 1 2).

The way it plays out is that rebinding is perfectly fine, because it's not
really any different from binding in the first place. The same way that

    
    
        (let ((x 10))
          (f x)
          (setf x (1+ x))
          (g x))
    

can be re-written as

    
    
        ((lambda (x)
           (f x)
           (setf x (1+ x))
           (g x))
         10)
    

That can itself be re-written as:

    
    
        ((lambda (x)
           (f x)
           ((lambda (x)
              (g x))
            (1+ x)))
         10)
    

If you'd like to read more about this sort of thing, Sussman and Steele's
"Lambda: The Ultimate Imperative" is a good starter:
[http://repository.readscheme.org/ftp/papers/ai-lab-
pubs/AIM-...](http://repository.readscheme.org/ftp/papers/ai-lab-
pubs/AIM-353.pdf)

~~~
kazinator
Rebinding is essential for recursion, which is a concept in mathematics. Given
a fib(x) function defined in terms of itself, the when we express fib(10), the
parameter x is simultaneously bound to a number of different arguments through
the recursion. We just understand those to be different x's in different
instances of the f scope.

Rebinding is also needed for simple composition of operations. Given some
f(x), the formula f(3) + f(4) involves x being simultaneously bound to 3 and 4
in different instances of the scope inside f.

------
mavhc
Is it really worth allowing assignment in places so weird that you also need
==?

Wouldn't it be easier to use = for everything and get rid of those weird edge
cases?

~~~
nfoz
Yeah I was pretty surprised when I found out that assignment and equality can
be totally syntactically separate and nonambiguous with miminal language-
design effort. Just get rid of the silly idea of allowing expressions as
statements.

Although even then it's nice to use different symbols because they are
different meanings. I don't like it when a word has different meanings
depending on context.

~~~
icebraining
_Just get rid of the silly idea of allowing expressions as statements._

I don't think that's enough. Take the two following Python lines:

    
    
      a = b = c == d
    
      a = b == c == d
    

No expression is being used as a statement, yet you can't syntactically
separate assignment from equality.

~~~
boomlinde
I think GP might have meant that to go the other way around, i.e. don't allow
statements to also be expressions, and more specifically, make assignment a
statement.

~~~
nfoz
Well first I was super intriguied by the example.

But I agree with your conclusion, that statements should not also be
expressions, so a = b = c shouldn't work (at least not the way we're used to,
that the b = c is an assignment "statement" that also produces an expression
value).

But in the end all this does is allow "a = b = c" to be a nonambiguous
statement meaning, in more familiar notation, "a = b == c". Not exactly clear!
So even though a language could use the same symbol for both assignment and
equality-check, I don't recommend it! Although I still like to keep statements
and expressions as strictly non-interchangeable constructs.

~~~
boomlinde
Just noting that I didn't mean to express any particular preference for
syntax, just addressing whether it's technically possible. Personally I'm fine
with = vs == being prevalent, but might prefer something like := and =
respectively.

------
wpietri
> Ken Thompson [...] personally, aesthetically, wanted to minimize the number
> of characters in source code.

Funnily, when Thompson was asked what he would do differently if he were doing
it over again, he said, "I'd spell creat with an e."

[https://en.wikiquote.org/wiki/Ken_Thompson](https://en.wikiquote.org/wiki/Ken_Thompson)

------
dkrich
I always liked DHH's take on these sorts of arguments (paraphrasing): who the
hell cares? Once you know the purpose of the '=' how often do you make
mistakes reading or writing code?

Whereas Java is all about protecting developers from themselves, Ruby (for
example) let's you get away without variable type declaration because at the
end of the day, how often do you not know whether a particular variable is a
string or an integer? Enough to justify enforcing declaring everything at the
outset or receiving errors throughout your code?

That's not to say that those enforcements never make sense. I think that
structured languages like Java are better for larger teams where enforcing
standards is more important than a smaller team. But there are other ways to
do that and a lot of time the rules make development a horrible experience.

~~~
lmm
> Once you know the purpose of the '=' how often do you make mistakes reading
> or writing code?

A nontrivial proportion of people who start trying to learn to program never
get past that point, so it's worth taking them into account.

> at the end of the day, how often do you not know whether a particular
> variable is a string or an integer?

Strawman. Types are not about the difference between a string and an integer,
they're about the difference between a user id and an order id, or a non-empty
list and a possibly-empty list, or...

~~~
bogomipz
>"Strawman. Types are not about the difference between a string and an
integer, they're about the difference between a user id and an order id, or a
non-empty list and a possibly-empty list, or..."

Can you explain - how is the difference between a string and an integer
different from the difference between a user id and an order id? You're
calling the OPs comment a straw man but I'm not understanding how your
examples are not the same thing given type system that understood all four of
those.

~~~
lmm
Many Ruby users don't realise that the type system can understand all these
differences. How often do you not know whether a particular variable is a
string or an integer? Not very often. How often do you not know whether a
particular variable is a user id or an order id? Much more often. So if you
think the only kind of difference a type system can tell you about is the
difference between a string and an integer, you vastly underestimate the
number of bugs that a type system could help you avoid.

------
optimuspaul
Simple, programming is like using Old Speech, the language of Dragons. We
cannot lie in that language and therefore when we make a statement it becomes
true. (In case I'm being too obtuse.. Earthsea)

But really, this is such a pedantic discussion, trying really hard to not get
sucked in.

------
chasedehan
In R, it is actually distinguished that way, example:

a <\- a + 1

a + 1 -> a # also works, but REALLY bad practice

But, so does

a = a + 1

Granted, there are a bunch of R haters (especially from people with formal CS
educations), I think this convention makes a lot of sense. While most will
disagree about the '<-' I like it from a code reading sense in that you know
that it is an assignment right away. Coming from a mathematical perspective
before learning to code, this makes a lot more sense in the 'assignment'
fashion.

In case you are wondering, the difference between <\- and = in R is in
scoping. For example, in the following function call:

foo(x = 'value')

x is declared in the scope of the function, whereas:

foo(x <\- 'value')

x is now declared in the user environment. Granted, that is not good practice,
but that is why there is a difference.

~~~
thalesmello
`->` is a bad practice? I like to use it at the end of a long `%>%` pipe.
Reading the whole thing feels a lot more natural.

~~~
chasedehan
The first time I ever saw that you could do that was in a blog post about
stringing at the end of the a series of pipes. I thought it was pretty neat
(and actually used it a couple times), then had problems when I couldn't
figure out why my code was messing up.

for example, this assigns a ggplot to 'plot': df %>% na.omit() %>%
ggplot(aes(x=x, y=y)) + geom_line() -> plot

That is really confusing in that the way most people would read it is that it
is something to be plotted. However, the assignment does occur and is masked.
having 'plot <\- df %>%' as the first line makes it clear that a new object is
being created.

We actually had to modify our style guide to prevent the '->'

------
kolpa
most of this article is covered in the Wikipedia page:

[https://en.wikipedia.org/wiki/Relational_operator#Confusion_...](https://en.wikipedia.org/wiki/Relational_operator#Confusion_with_assignment_operators)

but Wikipedia says: "The reason for all this being unknown. [footnote]
Although Dennis Ritchie has suggested that this may have had to do with
"economy of typing" as updates of variables may be more frequent than
comparisons in certain types of programs"

while the OP says: "As Thompson put it:

Since assignment is about twice as frequent as equality testing in typical
programs, it’s appropriate that the operator be half as long."

Thompson and Ritchie designed C together.

~~~
timbit42
Economy of typing definitely shouldn't be the #1 concern when designing a
language. Look at APL.

------
tom_mellior
> Prolog came out the same year as C and popularized logic programming, and
> you can sort of fake assignment with cuts.

Can anyone explain to me what this is supposed to mean? (I know Prolog, I
understand cuts very well. But I don't know what the author means here.)

~~~
hwayne
It means I don't understand Prolog very well and really shouldn't have
namedropped it :P

~~~
triska
Prolog is a good example of a language where "=" _doesn 't_ mean assignment.
In Prolog, "=" means _unification_ : You can read X = Y (which is =(X, Y) in
functional notation) as: "True _iff_ X and Y are unifiable". You can think of
unification as a generalization of pattern matching. For example, f(X, b) is
unifiable with f(a, Y) by the substitution {X → a, Y → b}. I think this aspect
would be a valuable addition to the article.

Fun fact: If (=)/2 were not available as a built-in predicate in Prolog, you
could define it by a single fact:

    
    
        X = X.
    

Thus, you do not even need this predicate as a predefined part of the
language.

------
sedatk
BASIC also came out with “=“ character for assignment in 1964, 5 years before
B. I think it also contributed to the adoption, considering how it was popular
in the 80’s.

------
msla
Because ASCII had already replaced the ← with the _, something which made PIP
somewhat harder to use, as this:

    
    
        PIP destination←source /switches
    

became this:

    
    
        PIP destination=source
    

or this:

    
    
        PIP destination_source
    

[https://en.wikipedia.org/wiki/Peripheral_Interchange_Program](https://en.wikipedia.org/wiki/Peripheral_Interchange_Program)

------
emodendroket
I've always had the notion that if I made a language I'd make the operators :=
and == so it'd be harder to accidentally use the wrong one.

~~~
pbhjpbhj
Wouldn't : and = make it equally (heh!) hard to use the wrong operator
notation?

~~~
klez
Using == and := would guarantee you never accidentally use = by itself (out of
habit from other languages) because that's not a valid operator.

------
Asooka
I always read it with an implied "let" in front, so it has always sounded
completely natural. It's also ergonomic to type, easy to read and while you
can confuse := and = on account of : being a small glyph even in monospace
fonts - you can mistake it for empty space if you're just skimming, == and =
are harder to confuse since one is twice as long as the other.

------
benatkin
I like = for assignment, but I don't like it for configuration. HCL and TOML
chose it, to their detriment, I think.

When it reads as "let x equal y" it makes sense. I think it makes good sense
for imperative programming. It makes slightly less sense for functional
programming. For declarative configuration, I think a colon makes much more
sense.

------
tobiasSoftware
The way I explain this to beginner programmers is that there are three types
of equals in math and programming: The math "=" means "these are equal" The
programming "=" means "make these equal" The programming "==" means "are these
equal?"

------
fspacef
"I don’t know if this adds anything to the conversation. I just like software
history."

This topic has my curiosity peaked as well. What is a good place to start
reading/understanding more about this?

From my understanding software development is a complex field that blew up in
multiple places at the same time.

------
hennsen
I value clarity and explicity a lot. And I’m someone who generally lines to
think about proper naming of a variable twice to make it easier for future
readers of code.

At the same time when reading

> How can a = a + 1? That’s like saying 1 = 2.

I think: Well, depends how you interpret it.

If the translation is „we state, that from now on, a is the previous value of
a plus 1“ it’s totally ok.

Not a big difference from saying

a = b + c

So i‘m not sure if the usefulness if changing all languages to using := is
that high that it’s worth to think about changing it in current languages -
and even when inventing a new language I’m not sure if it’s helpful.

I also wonder if reassignment, beside counters that need to be changed with
iteration/ appearance of the event to be counted, is a thing that should
generally be avoided if possible. Ok maybe in general everything where data is
transformed in iterations...

------
rhabarba
TIL: "BCPL later adding a floating point keyword. And when I say “later”, I
mean in 2018. "

~~~
karmakaze
That one really gave me a chuckle.

------
nailer
Because programming languages are typically designed for the tiny group of
existing programmers than the much larger group of future programmers. The
same reason unnecessary tokens exist, and 'drop' means delete in databases.
It's entirely cultural.

~~~
ben509
>Because programming languages are typically designed for the tiny group of
existing programmers...

So this is a dilemma I have while working on a new language. I'd like to go
with `:=`, but `=` is absurdly popular, and I'm trying to keep the language as
approachable as possible.

I don't think the clarity of `:=` is so compelling that it outweighs the `ew,
why are there colons in there` reaction that I think most novice coders would
have.

(Remove redundant commentary about database stuffs.)

~~~
TimJYoung
The key isn't whether you use := or =, it's whether you allow assignment in
expressions.

My advice: don't allow assignment in expressions. To me, it's like the case-
sensitive issue: the language designers think it's a useful feature, but it
actually works against _most_ developers.

~~~
ben509
I definitely agree that assignments should be statement level operations.

I don't think case-folding identifiers is helpful. The language has decreed
fooBar is the same as foobar, and that handles the error where you spelled the
same idea two different ways, but it fails silently on the error where you
spelled two different things a similar way. Worse, there are some people who
are very sensitive to case and will be confused, while others will happily
type their entire code in all caps.

I think a linter is the best way to catch these issues, and those subjective
rules are precisely the sort of thing that need to develop more rapidly than
the core parser.

~~~
TimJYoung
Yes, but again, the issue is whether most developers will be hindered or
helped by case-sensitivity in a language. Based upon my experience, identifier
case-sensitivity is simply making things harder than they need to be on the
developer.

Conceptually, what is the difference between these two identifiers:

myObjectInstance

MyObjectInstance

?

And the key here is the _reason_ for the difference: if it's a typo, then a
case-insensitive language design will allow it and no-harm, no-foul. If it's
_not_ a typo, then who wants to work on a codebase littered with identifiers
whose only difference is case ? :-)

~~~
ben509
> Conceptually, what is the difference

In Haskell, one is a variable, the other is a type, and that's enforced by the
language. It's the same, albeit by convention, in Java. There are a lot of
cases where you want to describe a type and a thing, so apple = new Apple() is
pretty reasonable.

When I think of case-insensitive languages, I'm thinking of Basic, LISP, SQL,
and those don't have a lot of type declarations.

And consider two counter-examples:

    
    
      my_instance vs myinstance
    
      things vs THINGS
    

The first shows case-folding is only a partial answer to ambiguous
identifiers. The second shows that differences in case can be very obvious to
the reader.

Those are motivators to me for pushing this off to the linter: there are a lot
of subjective judgements in what should and shouldn't be the same, and having
the language keep its rules for identifiers as simple possible seems like a
good separation of concerns.

My final concern is metaprogramming and interoperability. In SQL, for
instance, there are bizarre rules to work around case-insensitive identifiers.
If another system asks you for "myObjectInstance" and "MyObjectInstance", it
has to know your case folding rules to know those two identifiers are the
same.

> If it's _not_ a typo, then who wants to work on a codebase littered with
> identifiers whose only difference is case ? :-)

Ever worked on a Python project that interacts with Javascript, so it's snake
and camel case?

I generally agree, I'd just prefer a gofmt-style utility that would just
automatically resolve those and tidy everything up. I completely agree that
just chucking error messages is a poor answer.

Finally, here's a challenge, if identifiers are going to be folded by the
compiler: what locale should be used? In particular, how do you handle I, İ, i
and ı?

~~~
TimJYoung
No, in my example they're both references to an object instance - they're
simply identifiers. Languages that are case-insensitive tend to _force_ one to
use identifiers that are also descriptive as to their usage, which is very
helpful when reading code as you can tell a type from a variable from a....

Re: languages: Pascal/Object Pascal is case-insensitive, and is statically-
typed.

Re: SQL: all implementations that I'm aware of use case-insensitive
identifiers for all of the reasons that I've outlined. Any that don't are
problematic, at best.

Re: locales: the way that this is typically handled is by a) restricting the
allowed characters to the English alphabet (older), or b) by using Unicode
(UTF-16) encoding for source files (newer).

------
User23
Because K&R had terrible keyboards so they abbreviated everything as much as
possible.

Traditionally := was used for assignment, which makes sense since it is an
asymmetric symbol for an asymmetric operation.

~~~
jghn
There’s also <-, most commonly seen in R but draws it’s heritage from the APL
keyboard

~~~
nfoz
Fun fact, R also has -> (assign to the RHS instead of LHS), and "super-
assignment" <<\- and ->>, and also can use = sometimes too (and I think has
different semantics). Yay R.

~~~
bllguo
I write R daily and have always used = for convenience. I can count on 0 hands
how many times that has affected me. <<\- has its uses though!

~~~
bachmeier
FWIW, that's what Ross Ihaka does as well (or at least did in a presentation
that I watched - and pointed out that you can use = for assignment).
Personally, I think = for assignment is a disaster, and wish I could use <\-
and -> in every language.

~~~
neuxenian
I've used R since it was in beta form, and one of the most interesting things
to me (aside from the evolution of type hierarchy) has been changes in use of
the assignment operator.

When I started, = was the norm for assignment, with == for evaluating
equality. Later I started noticing that people were recommending <\- based on
scope concerns, but it was kind of subjective preference. Now I see articles
like this saying that the "preferred use" is <-, and some people don't even
know about =.

I agree = versus == can lead to tricky errors in code, but I still prefer =
for various reasons in general in languages (although I get the scope
arguments).

The reason is that = is shorter, and assignment is an definitional equality,
which to my impression is the whole point of programming in general usually.
As others have suggested here, between = and ==, = is by far the more commonly
used operator in meaning, so to me it makes sense to use = for succinctness.

In math, there is an "equal by definition" operator, with three lines, so I
could see that, but keyboards don't have that, so it's more steps. := is also
a kind of standard "by definition" usage as discussed in the article, but
again, it's more steps. I'd still prefer that over <\- in R.

~~~
jghn
Interesting. I started using it in 2000 and was working directly with members
of R-core at the time. My experience was that the only time I ever saw = used
was by DTL.

It really wasn’t until Google published their style guide and then later when
Hadley published his that I started seeing = in heavy usage.

To your point about = being shorter I wonder if the difference was that a lot
of the folks I interacted with were using Emacs with ESS which would
interpolate _ to <\- so they wouldn’t have noticed? Just a theory.

Either way I was taught from some of the R creators that <\- was evil and to
be avoided. It wasn’t until I stopped using R regularly that I switched, it
became too mentally taxing to change assignment operators when I bounced
between languages

------
danans
The Go language brings back the ":=" to mean declare and assign, while
inferring type.

a := 5

You can also equivalently do

var a = 5

I almost never use the latter within functions (only at module scope).

I believe the former is forbidden except within functions.

~~~
jug
I was puzzled by this decision of theirs though. They are so hell bent on
keeping the language as simple as possible with a minimum of keywords, but
apparently can't be arsed to just write _var a = 5_ like normal people, but
prefer to invent a whole new operator for it. Operators are often demanding
even _more_ of a reason to exist than keywords.

Then you also get the operator inconcistency between "assigning to a new
variable" and "assigning to an existing variable" and is it so important to
tell the two apart from within an operator, of all things?

When writing Go, I have been way more inconvenienced by its error handling
mechanics than having to tell that I want a new variable using a few more
characters.

------
tropo
The third option: an assertion of fact

A language could reasonably use plain = to let the programmer state that two
things are equal. In a debug build, this could be compiled into code that
validates the condition. A debug build would abort if the condition is not
met. For a performance-optimized build, the compiler could use the information
for optimization. It could be like the __assume keyword that Microsoft
supports.

~~~
smadge
This is essentially what ‘assert’ does in some C like languages except it
allows more than just asserting equality. For example:

    
    
      assert(length < 10)

------
robotresearcher
I always liked Pop11's assignment syntax:

1 => x

[ 10 11 12 13 ] => mylist

Reads and evaluates left to right. C seems backwards after that. (Also LISP-
type lists without commas).

------
notmarkus
It's ...odd... but I've always liked the simple elegance of (Meditech's) MAGIC
languages. Strict left-to-right, even in assignment and in math. Instead of "A
gets 1" (A = 1), it's "1 goes to A" (1^A).

    
    
        > 1^A
        1
        > A+A^A
        2
        > IF{A+A*A^B B}
        8

------
aap_
= is used for assignment in PL/1, a language ken and dmr were very familiar
with due to their work on Multics.

------
rootedbox
Pascal got rid of the confusion.. := is assignment = is comparison.

I really wish more languages had an specific assignment operator.

~~~
Taniwha
I think Pascal got all that from Algol68 (which in turn got stuff from
Algol60)

(Pascal is essentially the easy bits to implement from Algol68)

------
jrochkind1
Approximately 20% of this giant thread seems to actually have read the article
before offering their own musings.

------
nostalgeek
Well Ada uses := for affectation and = for actual equality.

In pure algorithmic notation, people might use <\- or <= instead.

------
kureikain
When I was in 10th grade, I found a Pascal book(I live in Vietnam so no
internet at the time), I have no computer too. I though it was a math book
since I aware of Pascal.

I was super confuse when I saw:

i := i + 1

I'm not sure how I get used to it but when I discover Erlang I feel so much
happy since we nolonger has that in Erlang.

I wish more language follow it.

------
willtim
IMHO, it was a mistake for some languages to make "=" mean assignment. Algol
and Pascal got this right and used ":=" to mean assignment. Even the use of
"variable" is wrong when talking about mutable memory. "Assignable" would be
better.

~~~
timbit42
Both excellent points.

------
j2kun
= has contextual meaning in math, why not programming? It's not like we can
fool ourselves into thinking that _tests_ for equality don't also have wildly
different meaning depending on context. No operator has a universal meaning,
nor should they.

~~~
Guthur
Can you provide an example where equals sign is not equality I'm curious.

~~~
j2kun
Most equivalence relations eventually drop any special notation in favor of =

In general, = is not rigorous. It's used as a stand-in for the word "is".

Another example is when someone writes x = 1, ..., N, meant to imply x is
changing, not that x is equal to a tuple. Also the index in summation
notation, which really is an assignment as in programming. I could go on.

------
mwrouse
While this is an interesting article on history, this isn't an actual
criticism, is it? I've never heard this criticism.

I really don't think saying "a = 1; a = a + 1;" is the equivalent of saying "1
= 2" because "a" is a variable.

~~~
jholman
It's a very common criticism.

And as a teacher of programming to adult students, this causes a small amount
of wasted time with the overwhelming majority of students, because they know
what "=" means, even the non-mathematical ones. Usually not a huge obstacle,
but a perceptible one.

And once they learn that it's a mutating assignment, some (small) fraction of
students continue to forget, for an infuriatingly long time, which direction
the mutation goes.

------
glorioustao
Coincidentally I am just reading the <<Programming in Ada 2012>>, and found
this in the introduction chapter:

> C history ... The essence of BCPL was the array and pointer model which
> abandoned any hope of strong typing and (with hindsight) a proper
> mathematical model of the mapping of the program onto a computing engine.
> Even the use of := for assignment was lost in this evolution which reverted
> to the confusing use of = as in Fortran. Having hijacked = for assignment, C
> uses == for equality thereby conflicting with several hundred years of
> mathematical usage. About the only feature of the elegant CPL remaining in C
> is the unfortunate braces {} and the associated compound statement structure
> which was abandoned by many other languages in favour of the more reliable
> bracketed form originally proposed by Algol 68. It is again tragic to
> observe that Java has used the familiar but awful C style.

------
antoineMoPa
TI-Basic, which I used on my TI-84 plus used ':=' for assignments like ALGOL.

[https://en.wikipedia.org/wiki/TI-BASIC](https://en.wikipedia.org/wiki/TI-
BASIC)

------
sideshowb
Bcpl still exists in 2018?

~~~
hwayne
Here's a PDF about running BCPL on a Raspberry Pi:
[http://www.cl.cam.ac.uk/~mr10/bcpl4raspi.pdf](http://www.cl.cam.ac.uk/~mr10/bcpl4raspi.pdf)

It's aimed at teaching programming to 10 year olds no prior experience. One of
the first examples is implementing RSA.

~~~
thedirt0115
Implementing a cryptosystem is one of the first things for 10 year olds with
no prior programming experience???? That seems intense compared to Scratch,
etc.

~~~
jandrese
The math is pretty straightforward. I assume they aren't implementing all of
the surrounding logic that makes crypto such a bear.

~~~
thedirt0115
I don’t mean so much that it’s super difficult, I’m just imagining that
10-year-olds would rather be making pictures move around on the screen over
doing a math thing that they might not yet understand the importance of. I
could be wrong, it’s been quite a while since I was 10 :) I was trying to
imagine 10-year-old me reading that section about RSA in the thing they linked
to.

------
Quarrelsome
As someone that's done a bit of Delphi I think he's missed the crucial issue
at play: If you use := as assignment your code just looks like a vertical
cascade of penises.

------
usernum3hundred
this might not be fact but I like to think that the colon in := might have
been dropped just like diacritic symbols were dropped from the English
alphabets. I am not a native English speaker so I had similar issues learning
the English script. It was particularly hard to grasp things like why 'do' and
'go' are pronounced differently. But overtime I released that eliminating
extra characters reduces a lot of unnecessary complexity and makes your
writing faster.

------
Aardwolf
= is not _that_ bad imho, if you see the thing before the = as next state.

So in "x = x + 1", x in its next state is mathematically equal to x + 1 in the
state before the assignment

------
ggm
At one level, the syntactic difference between = and := and == is moot. At
another, since it expresses intentionality (semantic intent) its quite
important.

"takes the value", "is equal" and "becomes equal to" are not saying the same
things.

What matters is inside the parser for the language, and expressions (as in
spoken or written words) between people about the language. Confusion abounds
in the latter, but a well designed language doesn't have moments of confusion
in the former case.

Some of the choices incur backtracking cost parsing the input. Some don't but
incur more keyboard presses per unit of code expressed.

------
AdmiralAsshat
Well that at least gives me a good idea of why `:=` cropped up in Go. Having
never studied anything older than C, it caught me by surprise.

~~~
taborj
Also used in Pascal for the same purpose.

~~~
emodendroket
Also Visual Basic.

~~~
jwilk
No? VB uses = for assigment, just like other Basics.

~~~
emodendroket
It uses := for named arguments.

------
smadge
If x = x + 1, then x - x = x + 1 - x, then 0 = x - x + 1, then 0 = 0 + 1, then
0 = 1. This is why ‘=‘ is a terrible symbol for assignment.

------
epx
I've always preferred the Pascal's :=

------
lucidone
I've always taken assignment to map to 'is', as in '1 + 1 is 2', or 'const foo
is bar'

------
petulla
Are there any good software history books that describe how the languages
influenced each other like this?

------
dmh2000
assuming you are ok with mutation its just syntax. = means assignment so you
only have to type one character. == means equal, so you have to type two. it
could be the other way around with := and = but its really a non-issue.
there's all kinds of weird syntax out there.

------
aknoob
I think the question should be why is assignment operator represented using
"=" ?

------
agumonkey
more broadly, why schools are merging reduction and equality in arithmetic ?

~~~
jwilk
What do you mean?

~~~
agumonkey
in primary school the focus in expressions involving = is reduction more than
equality:

    
    
        2 + 2 = 4
        <n terms> = <constant>
    

I don't recall teacher showing you equalness through stupid but important
ideas:

    
    
        2 + 2 = 2 + 2
        2 + 2 = 2 + 1 + 1
    

all these are equal, and it's important later on when expression, with
variables, aren't reducible to a constant but to another expression which is
equal to the other one. IMO it would help a lot for people to try to simplify
a problem into a known identity or interesting form (for instance the 'trick'
of adding and subtracting one to get closer to binomial formula or other)

------
te7eyw8u
In Smalltalk it's ←

------
hullsean
for me it’s := and probably always will be. those fond memories

------
dboreham
Should be ->

Or perhaps <-

~~~
smadge
I would definitely prefer ‘destination <\- source’ as it reflects the actual
flow of data.

~~~
tom_mellior
In what way would 'source -> destination' _not_ reflect the "actual" flow of
data?

~~~
smadge
I would be ok with that too!

I must have misinterpreted dboreham as suggesting

    
    
      destination -> source
    

Which is very confusing to me.

~~~
dboreham
The arrow always reflects the direction of flow. Difference is just whether
you like to have destination first or last. Basically are you Motorola or
Intel..

------
cup-of-tea
It isn't just mathematically unsound, it's the cause of many errors,
especially in C. Certainly a "million dollar mistake".

A classic way to guard against accidental use of assignment in logic
statements is to write it "backwards", i.e.:

    
    
        if (2 == x) {...}
    

Since (2 = x) won't compile, while (x = 2) will not only compile but might
appear to work for a very long time.

~~~
v_lisivka
It's better to use -Wall -Werror options for C compiler.

~~~
cup-of-tea
That won't always catch the error and even if it did, why is it better?

~~~
ben509
-Wall can almost always catch the problem as it will insist on redundant parens surrounding an assignment. So you can only screw it up if you typed extra parens for an equality expression.

Variable on left is conventional, it's how people sound it out in their head,
so it's just easier to process mentally when the expression becomes more
complex.

Yoda syntax catches that single error at the expense of making all equality
expressions harder to write, read and maintain.

And, besides, if you're going to use Yoda syntax, you're going to want your
linter to enforce it... at which point you may as well turn on -Wall anyway.

~~~
greenhouse_gas
Also how do you prevent "if(a=b)" if both sides are variables?

~~~
ben509
I will let clang's _amazingly_ detailed error messages speak for themselves:

    
    
      ben@burnination ~ $ cat test.c
      int main() {
          int a = 3;
          int b = 2;
          if (a=b) {
              return 1;
          } else {
              return 0;
          }
      }
    
      ben@burnination ~ $ clang -Wall test.c
      test.c:4:10: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
          if (a=b) {
              ~^~
      test.c:4:10: note: place parentheses around the assignment to silence this warning
          if (a=b) {
               ^
              (  )
      test.c:4:10: note: use '==' to turn this assignment into an equality comparison
          if (a=b) {
               ^
               ==
      1 warning generated.

------
mortdeus
because in math it means assignment. y = mx+b

That is an assignment. There is also a math symbol that specifically
designates equivalence.

~~~
qntty
The concept of assignment only makes sense in a context with a time axis.
Computation has a time axis (location of the instruction pointer) but math
does not.

~~~
YOrlandoLO
Nope. Logical axioms are required logically, but not associated with time.
Comprehension is associated with time, so I can understand how you might
arrive where you did.

~~~
qntty
Sorry but I don't understand how you're using the word 'comprehension' here. I
agree that logical axioms aren't associated with time (this is what I mean
when I say that math doesn't require an idea of time).

------
tomxor
About once every year I have a brain fart on a sleepy morning and confuse
myself by using = for comparitors and or == for assignment... shortly followed
by "Nnarhh".

[edit]

:P LOL at downvotes, HN is no place for silly annecdotes "this is serious
things we dooo".

~~~
astrobe_
There are better places if you just want to talk about yourself.

~~~
tomxor
> There are better places if you just want to talk about yourself.

hmm, I don't agree with what you are implying defines acceptable comment
content on HN. There are many if not a majority of comments highly rated on HN
which are highly personal that necessarily talk about themselves, it's part of
what makes those comments interesting, if we all commented like wikipedia
articles it would be a dull place indeed. My comment maybe flawed in the eyes
of other HN readers, but not for the reason you have highlighted.

In my case it's is both personal and relevant but to be honest - not
interesting or insightful which is probably why someone mean enough gave me a
downvote... but then afterwards I broke the "first rule of fight club" which
on HN is equivalent to throwing yourself to the wolves, I accept that, and
also can't help it, it's just my nature, I don't self censor for points.

