
Constantly Confusing ‘const’ - _getify
http://blog.getify.com/constantly-confusing-const/
======
pornel
I don't agree with this style.

`var` is broken. Don't try to find a use-case for it. Just don't use it.

It would be nicer to have real, deep immutability, but `const` isn't it.
Therefore, use it for what it actually is, not what you wish it was. If you
don't intend to reassign a reference, then mark the reference constant. That's
it.

It may be surprising, but it's quite easy to write JS where almost every
declaration is `const`. When every mundane variable is `const`, then the more
complex initializations/data flows/accumulators really requiring `let` stand
out, which is very useful for reviewing code ("let" = "warning: there may be
an `else` or missing `switch` case that will leave that undefined").

Because `const` requires to be initialized at the time of definition, you know
the variable is valid for its entire lifetime. When you find its value was
wrong, there's only one place where the value could have come from (you don't
need to comb the function to look for reassignments).

~~~
_getify
> `var` is broken

Nonsense. Revisionism at its finest.

But that's an argument I made in a different blog post:
[http://davidwalsh.name/for-and-against-let](http://davidwalsh.name/for-and-
against-let)

> It would be nicer to have real, deep immutability, but `const` isn't it.

Yep, agree with you on that. That was one of the main points of my post.

> Because `const` requires to be initialized at the time of definition, you
> know the variable is valid for its entire lifetime.

No, that's where you're mistaken. All you really know is that the variable
__assignment __is reliable. If the assignment happens to be of an immutable
value, great.

But given the choice between these two guarantees:

1\. The assignment is immutable

2\. The value is immutable

(1) is almost pointless -- and a quick scan of your small block where it's
scoped will verify that or not.

(2) is the absolute important one.

`const` masquerades as (2) when it's really only (1). That's what I don't like
about it.

~~~
Retra
Your blog post doesn't make a very strong argument, honestly.

~~~
_getify
I would genuinely (no sarcasm) like to read a blog post that makes a stronger
argument (in either direction) than mine. Most blog posts I've read about
`const` cite very flimsy things like "it makes my code more readable" without
any real meat as to why that's true. I tried to debunk that with careful
thought. If someone has more convincing arguments besides subjective opinion,
I'd love to read them.

~~~
Dylan16807
>I tried to debunk that with careful thought.

Well you didn't really succeed. Your argument against using const comes down
to "someone might violate expectations or remove the word const, so let's not
even try". I don't agree with that.

Traditional constants are used to show that nothing changes in large swaths of
code; showing how much benefit you get in a standalone 12 line function is not
meaningful.

Also, calling function scoping bad is not revisionism. That is not a new idea,
and does not depend on 'let' existing.

Edit: And the the article you linked about let is saying so many ridiculous
things I won't even try to respond to it, but jeez. 'implicit'

~~~
_getify
> Your argument against using const comes down to ...

You did an absolutely horrible job of summarizing even remotely what my
argument was, so I guess "I won't even try to respond to" this, since you
either can't critically read or didn't care to this time. jeez.

~~~
Dylan16807
That's what you devote several paragraphs to. I'm not sure how else you
explain quotes like "the likelihood is that a developer who needs to change a
variable and gets a const-thrown error about it will probably just change the
const to let and go on about their business."

I don't care to argue about 'let' because this is a post about 'const'. I was
writing a rebuttal in the previous comment but realized it was way too off-
topic. But your definition and reasoning for "implicit scope" hurts me to
read.

------
codecurve
Why not use `const` as default? I would argue that using `let` instead is a
premature optimization of readability.

It's easier to reason about a variable if you know it will always be one
value—even if the value may be mutated (which is unfortunate).

`const` is a simpler construct. It has less rules and I would always suggest
that using `let` will introduce complexity that only needs to be there when
you can identify a genuine need to re-assign a value to your variable.

That said, I enjoyed the post. It's a good read!

~~~
_getify
> Why not use `const` as default?

The argument I made toward the end of the post is that refactoring from
`const` back to `let` is more risky than the other way around.

Moreover, surveying my own code, honestly, the vast majority of my
declarations should be `var` or `let`, and only a much smaller amount being
`const`. I think a lot of people are rushing blindly to `const` without
realizing its full behavior.

> [`const`] has less rules ... using `let` will introduce complexity

I think this is completely backwards. `let` has no special caveats (other than
the TDZ thing, which they both have), whereas `const` has this caveat that
it's only about assignment bindings and not about values.

Imagine a piece of code that has `const x = 2` that you later refactor to
`const x = [2]`. The complexity is, you now have to contend with the `[2]`
being a mutable value where `2` wasn't, and `const` sorta pretends to keep you
safe but doesn't.

That's the complexity I disfavor.

~~~
adrusi
_`const` has this caveat that it 's only about assignment bindings and not
about values._

 _Imagine a piece of code that has `const x = 2` that you later refactor to
`const x = [2]`. The complexity is, you now have to contend with the `[2]`
being a mutable value where `2` wasn 't, and `const` sorta pretends to keep
you safe but doesn't._

If these semantics aren't instantly obvious to you, then that's emblematic of
a serious gap in your understanding of programming. I say this not with the
intent of shaming, but to recommend that you (and the very many other people
with the same lapse) invest some time into developing intuition about
reference semantics. The best way IMO is to get initmately familiar with a
language that has first class pointers or otherwise explicit indirection.
Learn C, get good at C, write something big in C. Focus on the pointer
semantics and you'll come out a significantly better programmer in languages
where pointers are slightly less immediately visible.

Of course if you're making this recommendation because you work with other
people who have a lapse in their understanding of references I can understand
that. I would encourage you, however, to try to fix the problem rather than
work around it by stunting the language. After all, it's an issue that will
crop up everywhere, not just the semantics of `const'.

~~~
_getify
Oh, I see. I just need to learn more. The problem is I just don't know JS (or
other langs for that matter).

[http://YouDontKnowJS.com](http://YouDontKnowJS.com)

~~~
abritinthebay
I agree that saying this issue is "emblematic of a serious gap in your
understanding of programming" is.. well.. douchebaggery.

However I feel a lot of the article and many of your posts about it in here
come down to "it makes me feel uncomfortable" which.. I mean, ok. Sure. I hate
spaces for indentation and think double quotes are better (and I have reasons
for both)... but I don't say there's no use to the other options.

I feel you're throwing the baby out with the bathwater here.

 _Should_ const probably have been about value immutability too? Yes, I think
so. I _totally_ agree. That's a REALLY important topic to discuss. Maybe pitch
it to the ES2016 committee as an iterative upgrade to const?

But as it stands it _does have value_. Yes it _mostly_ just codifies what
programmers original did as a language construct but it does also stop
redefinitions which was an annoyingly common issue. So it's progress. Small,
incremental, and not as full-featured as we'd both like... but it's progress.

Drawing attention to the issues with const is important... but there's no
reason to rail so hard against its _usage_ when it's understood to have those
limitations... is there?

~~~
_getify
But my post did actually conclude the cases where it's useful. It seems like a
lot of people here only read the first half of the post and stopped.

I don't think `const` should be removed. I just don't think we should lead
with it. I'm not sure why that's not coming across except for the fact that
the post isn't being read.

~~~
abritinthebay
Hmmm I think maybe your tone comes across stronger than you mean it then.

Because, while you do say that, it comes across as a sort of "meh, it's not
totally useless but I still hate it" kind of thing at the end.

Especially as you spent the last... like 2000 words trashing it.

------
aphexairlines
const conveys additional information. It says "this name will not be rebound,"
not just to the reader, but to the machine interpreting this as well.

As a reader, I know that after reading a const line I don't have to check if
someone rebinds this name before each use site -- it's impossible.

Interpreters and static analysis tools use this information to stop you when
you write a piece of code that rebinds the name, asking "did you really mean
to do that? You said you wouldn't."

~~~
_getify
> I know that after reading a const line I don't have to check if someone
> rebinds this name before each use site -- it's impossible.

This turns out to be almost useless information for most of us, since the real
problem is not re-assignment, but mutation of the value (in the case of non-
primitives).

`const x = 2` feels great emotionally, but `const x = [2]` has the feeling of
safety without any of the guarantee.

This is a classic case (quoted from Crockford regularly) of a utility that it
sometimes useful and sometimes harmful (aka not useful), and there's a better
option (`let`), so the better option should generally be preferred.

I only use `const` (refactor from `let`) when a piece of code is reasonably
complete and I'm pretty sure re-assignment will not ever be appropriate.
Guessing at that before writing the code is a premature optimization.

And guessing wrongly and having to refactor back to `let` later is more risky.

~~~
AgentME
> `const x = 2` feels great emotionally, but `const x = [2]` has the feeling
> of safety without any of the guarantee.

Const is perfectly sensible with references to mutable objects too. The latter
guarantees that x will always point to the same mutable array. If you pass a
reference to the x array to a function which needs to mutate that specific
array or observe it for changes, then it may be important that x is never
rebound to a different array. Consider the following code:

    
    
        const x = [5,6,7];
    
        Object.observe(x, function(changes) {
          console.log('changes', changes);
        });
    
        // ...
        // time to clear the array
    
        // WRONG! The code observing changes to the old x array will not see
        // this change or future changes to this new array. Because we used const, this
        // will trigger an error and immediately show us our mistake.
        x = [];
    
        // CORRECT. This mutates the array instead of creating a new empty array.
        x.length = 0;

~~~
_getify
> If you pass a reference to the x array to a function

This notion (concern) is meaningless in JS, since when you pass any reference,
it's always a reference-copy, so there's no value nor assistance that `const`
provides.

~~~
AgentME
Const usage prevents a bug in my example directly above!

------
Kenji
To be honest, I've been following the rule of using capital letters for things
that should remain 'constant'. If everyone working on the project knows that,
it works like a charm, never had any issues with it. But it's nice to have
const now. So, I do see value in the const feature even if it doesn't protect
me against a commit by the devil himself who changes the content of const
objects.

Long story short: If you want to be annoyed about this feature, then more
power to you. I won't be.

------
cbuq
> I think the likelihood is that a developer who needs to change a variable
> and gets a const-thrown error about it will probably just change the const
> to let and go on about their business.

If this is the core argument to not using 'const', then you are out of luck
trying to enforce any coding style. I might as well just delete any code that
doesn't make sense.

~~~
_getify
It's not the core argument. It was a tangential side note in the blog post.

------
PhiLho
One advantage const can bring (at least when used with primitives or frozen
values) can come from JS IDEs: if they detect a value is const, they can
report its value when hovering the variable name, in a static way.

That's what Java IDEs do with static final variables.

------
mbrameld
> To most developers, it means that your LUCKY_NUMBERS will always be 12, 19,
> and 42.

Is that really true? I would assume the opposite. Most developers have used
Java or C# or any of the other languages that have similar reference
semantics. I would agree if you qualified that with "beginner".

~~~
zyxley
I suspect if you did a survey, there would be plenty of programmers who would
reply "it works like this, except these languages do something different",
because "const means immutability" feels "right" despite many mainstay
languages doing it differently.

------
gadrfgaesgysd
And people complain const in C is too complicated...

~~~
evincarofautumn
How do you mean? All this post is saying is that “const” in JavaScript is the
same as “final” in Java—it lets you make immutable references, but not
immutable objects. In C terms, you can express this:

    
    
        T *const x = ...;  // Immutable pointer to mutable T.
    

But not this:

    
    
        T const *x = ...;  // Mutable pointer to immutable T.
    

Even so, I don’t agree with the author’s argument that “const” is to be
avoided. It does offer some protection against minor errors, which is not
nothing.

~~~
_getify
I don't think my argument was to avoid `const`. I think my argument was to
pick `const` at the end rather than at the beginning. I feel those are
different arguments.

~~~
evincarofautumn
To be clear, “choose X last” does give the impression of “avoid X”, by which I
don’t mean “don’t use X at all”. I disagree, but it’s a small matter; it’s not
as if it would bother me to read your code.

------
_getify
disclosure: self submission

