
Loyal Opposition to Const, Private, Freeze, Non-Configurable, Non-Writable... - tswicegood
https://mail.mozilla.org/pipermail/es-discuss/2011-November/017872.html
======
lmkg
I'm somewhat of two minds about this.

On the one hand, I think he has a point that said features of JS.next are
cutting against the grain of present-day JS. There are quite a lot of people
programming in JS, many of whom may or may not deserve to be called good
programmers but who nonetheless can produce functioning web pages, that would
have to switch to a very different coding model to work with JS using these
new features.

On the other hand, it's difficult to program your code when you know than any
of your invariants can be accidentally stomped on by any other code that
happens to run on the same page. It's also difficult to write libraries when
everything's guts are exposed, even with red tape. Raymond Chen over at MSFT
has an entire blog that could be titled "How Implementation Details Become _De
Facto_ Interfaces Due to Insufficient Encapsulation."

I think my final thought on the matter, is that when you think about it, it's
really quite silly that we only have one language for front-end web
development. It is, in fact, unacceptably silly. Like, seriously guys, what
the hell? This is totally crazy. If you want to do server work, or non-web
client applications, or embedded, or whatever else, you have a full array of
programming languages. These run the gamut from ball-gag-and-leather-
straitjacket static languages to walk-into-anyone's-house-and-drink-their-milk
dynamic languages, from concise expressive languages to low-level bit-fiddly-
ones, from parens to curly braces to significant whitespace to perl.

On the web we have JavaScript. Not that it's a bad language, it has its warts
(what doesn't?) but it's actually a cute little language. But I don't have the
option of using a language with static guarantees. Or deterministic memory
management. Or asynchrony. Or macros. None of these are strictly better,
they're all just personal preferences, but the point is, you don't have the
choice.

That lack of choice is probably what's driving these against-the-grain
additions to JS.next. They're adding more features to JavaScript so that it
can cover some of the bases that it currently doesn't, and all the different
directions it's being pulled in are understandably causing some stress. I
think it's the wrong solution, but it's also the one with the easiest
transition path. The ideal solution, is that we could use different languages
from different paradigms, but how the hell do you crowbar them into existing
browsers?

So uh... do I have conclusion? I dunno, language evolution is hard, let's go
shopping.

~~~
davedx
Being able to declare member variables as private (really private, not the
private alluded to in Ruby) is good. As the OP said, you don't _have_ to
declare a member variable as private if you want relaxed 0constraints. But
when you want to for good design reasons -- it's great that the language you
are working with allows you to do so.

~~~
repsilat
If you really need private member variables you can probably whip something up
with lambdas, though it might be a little awkward.

~~~
reissbaker
It's super easy:

    
    
      function A {
        var secret = 0; // <---------- private variable
        this.method = function() {
          alert(secret);
        };
        this.increment = function() {
          secret++;
        };
      }
    
      a = new A();
      a.increment();
      a.method(); <-------- prints 1
    

The main problem is just the inefficiency of declaring methods inside
constructors.

Edit: Hence, the keyword.

------
noelwelsh

      "const" does not add anything new to a variable.
      If you don't want to change the value of a variable ...  
      don't change the value of the variable.
    

I've got a better idea: how about we mark the variable in some way and get the
compiler to remember this for us. Then, when we come back to the code in 6
months, we won't make mistakes.

I have a decade of experience in "dynamically" typed languages, and I prefer
modern statically typed languages in _almost_ all situations. Now it turns out
you can have both: see Racket and Typed Racket for instance.

~~~
stdbrouw
"I've got a better idea: how about we mark the variable in some way" — if all
you need is a mark, the Python convention to add an underscore in front of
your private method or variable works just fine, as does the convention to
make constants uppercased. I've seen quite a bit of JS code use these
conventions too.

The trouble with true private/protected variables is that you never really
know how your code is going to get used and which parts of your library people
may want to mess with. In that case, you can either play around with things
you aren't really supposed to touch, or if that's not possible because
everything's encapsulated, being in a hurry, you'll just fork the code and
turn private methods into public ones. Both approaches suck, and the problem
exists regardless of whether your language supports `private` and `const`
keywords or not.

~~~
ootachi
"if all you need is a mark, the Python convention to add an underscore in
front of your private method or variable works just fine, as does the
convention to make constants uppercased. I've seen quite a bit of JS code use
these conventions too."

Until you have a user subclass your class and accidentally stomp over one of
your private names, causing your class to mysteriously fail. I've been bitten
by this before, and it'd be nice for JS to offer a solution.

------
geraldalewis
jashkenas is one of the most prolific and talented JS devs around
(CoffeeScript, backbone.js, underscore, docco are among his credits). I can
see why he and other library producers would want as much flexibility in the
language as possible.

Library _consumers_ , on the other hand, will reap the most benefit from the
proposed constraints.

`private` is important metadata for a library consumer. Documentation
generators can ignore private members, and private tags serve as roadsigns
that the member can be ignored if one is only interested in the API. `private`
is a very powerful filter.

The same can be said for `const`: indicating a value shouldn't change
eliminates one more thing one needs to hold in their head as they explore a
lib's boundaries.

I don't care at all about the performance benefits; I care about
communication. `private` and `const` are nearly-free, expressive
documentation.

I actually like Ruby's "red tape" approach; it offers library consumers
helpful metadata while still allowing flexibility. Maybe the best solution is
for library developers to rigorously use the _private and CONST naming
conventions, and reserve `private`, `const`, and `freeze` for security-
sensitive code. Wouldn't that offer the most flexibility?

~~~
davedx
To be honest, there are very few languages where 'private' and 'const'
modifiers can't be gotten around. That doesn't decrease their usefulness
though if people agree to code to the _spirit_ of the language's design.

------
lux
This is similar to the divide I see in the PHP community.

There's been such a big movement towards more strictness, more Java-like
features and frameworks, while the more interesting development today seems to
be moving away from that, towards more concise, flexible, and expressive
languages like Ruby and Python, more FP ideas, and the rise of server-side
Javascript.

I started programming professionally in Perl, where you were handed a loaded
gun and learned the hard way not to shoot yourself in the foot. I appreciate
the discipline that demands, making you think hard about what you're doing.

I really hope the Javascript community doesn't start to compromise its dynamic
nature and lose one of the things that made it great. There are areas where
syntax could certainly be improved/made more concise, but keep the dynamism
and flexibility all the way (and add more!). Good on Jeremy for fighting for
that.

------
raganwald
My general feeling is that these un-features take things away, and what they
purport to provide in exchange is fewer bugs by virtue of being able to check
certain constraints at ‘compile time’.

I’m all for taking things away, but I personally want more in exchange. For
example, if you’re going to give me immutable or const declarations, give me
lazy evaluation as part of the bargain.

So I’m not opposed to taking things away, I am just optimistic that we can
provide a lot more value than ‘constraints’ in exchange. And if we aren’t
going to provide more value, I think we’re setting our sights too low.

~~~
politician
Have you considered the value that these keywords add to a team environment,
or as reminders when visiting an api that you haven't worked on in months?
It's something a little more standardized than "_privateVar" and "maxCount =4;
// NOTE: Constant Variable!"

~~~
raganwald
I have, and speaking as a guy who spent a big chunk of his career working with
large teams on large code bases, I think private and const are small potatoes
next to really big domain-specific semantic constraints. So to me, providing
small value in exchange for making other things harder to do is not a win.

It feels like we're circling around a local maximum and nobody is trying to
make a really big leap when thinking about JS.next. We're getting the warmed-
over leavings of middle-of-the-road language ideas.

If you really want constraints that are tailored for a team environment, make
them programmable and put const and private in the standard lib. Then let
Alice write something that prevents Bob from putting text in a SQL query or
opening up an XSS vector in raw HTML. Or let Carol write something that
ensures that all code makng certain writes to the database have an
authorization check baked in.

~~~
BrendanEich
FYI, <http://disnetdev.com/contracts.coffee/> is built on ES6 proxies and
CoffeeScript.

I agree on circling a local maximum, but some of this is just JS catching up
to Ruby and Python. Syntactic affordances for usability that desugar to only
lightly extended kernel semantics.

The big ticket items are modules, proxies, weak maps, binary data, and the
like.

When I liken JS to x86, I'm not comparing it to assembly so much as to a
ubiquitous target for compilation. JS is even stickier and longer-lived than
x86 -- witness ARM's rise on mobile while the web evolves mostly-compatibly,
including JS content and the JS language.

Contracts and macros are on the Harmony agenda, further out.

~~~
Andi
I came across contracts some time ago and found it very appealing and
inspiring, but for all my professional projects I am successfully using my own
library schema.js ( <https://github.com/akidee/schema.js> ) - you can use it
in pure JavaScript, too. (Usually I do not validate forms on the client-side,
since the data must be validated on the server-side anyway. And with
schema.js, you can add custom localized error messages.) Furthermore,
schema.js has several modes that allow tolerant adaptation of values, so that
they can be casted. "5", for example, is casted to 5. But you can switch to
strict validation mode as well. You can do everything, that contracts allows,
with schema.js, too. The best is that, with JSON schema, 1) you define secure
validations, since with the default properties you do not forget important
constraints, and 2) you do not need to test your validators any more.
Conclusion: I agree that such features must make it to the core of a language.
Probably you can find some useful ideas in JSON schema and schema.js. I found
the JSON vocabulary to be very useful to validate JS data.

------
swannodette
As a long time writer of JavaScript I say bring it on. If you want JavaScript
to succeed outside client browsers in a big way you must to consider
performance. If it wasn't for incredible perf gains in the past couple of
years you would not see JavaScript pushing into the server side.

However JavaScript performance still leaves much to be desired -
[http://stackoverflow.com/questions/6216888/is-nodejs-
faster-...](http://stackoverflow.com/questions/6216888/is-nodejs-faster-than-
clojure).

I want JavaScript to close the gap without sacrificing dynamism. And it won't
- these feature are _entirely optional_ and they free the implementors to make
assumptions which allow further optimization.

"Pay for what you use"

To be totally honest I don't see myself writing plain JavaScript much longer,
I'm closing in on 7 years now. At work I use quite a bit of CoffeeScript and
very likely in the near future I'll leverage ClojureScript.

~~~
true_religion
Why not allow for C extensions to Javascript, and create a compiler capable of
easy generation of these extensions with optional typing?

An example of this would be Cython for Python, which lets you get to C speed
within 1 to 5% slow down due to interfacing with Python, and it has you write
in a Pythonic dialect of C/C++.

~~~
william42
Because, all else being equal, writing your code in one language is better
than writing your code in two languages.

------
recursive
> "private" does not add anything new to a property. If you don't want the >
> property to be used outside of the class ... don't use the property outside
> > of the class.

I think the author missed the point of private, because it does add something
new. Specifically, it adds the ability to know that the property is not being
altered outside the class without reading the entire code base.

~~~
prodigal_erik
Not even reviewing the code can prove that any property is inaccessible, when
its name could be constructed anywhere at runtime and used via
object[propName]. Without actual language and runtime enforcement, there are
almost no pervasive changes safe enough to make without the kind of thorough
regression testing most teams aren't prepared to do. Which is not to say they
don't do it anyway, and sometimes get lucky.

------
erichocean
I've done a lot of low-level JavaScript work via my time developing SproutCore
1.0.

Jeremy is right on. Keep JavaScript open. Add red tape if you must, but don't
ACTUALLY lock it down. The openness (and lack of package management) are
killer features.

We are lucky that JavaScript is the language in the browser; it could easily
have been Visual Basic (shudder).

------
jxcole
He seems to be under the misapprehension that libraries would be impossible or
extremely difficult if you added restrictions to the language. This is
illogical. Languages with many _more_ restrictions, like Haskell, can still
have useful libraries. Sure, jquery wouldn't be able to work in exactly the
same way it does now, but it could still work. (I would imagine wrapping
objects instead of actually changing their prototypes).

Also, he doesn't go over the most useful aspect of static OO, which is
interfaces. Being able to force an incoming argument to have attached methods
often makes code much simpler, because you don't have to deal with the
possibility of someone passing different arguments into your function.

Arguments like this usually degenerate into shouting messages, so I would like
to conclude that even though I am a huge fan of static typing, I don't think
it's for javascript. You can always add a static type checker on top of a non-
static langauge, so people like me will be happy. It might be more difficult
to go the other way around.

~~~
oconnor0
> He seems to be under the misapprehension that libraries would be impossible
> or extremely difficult if you added restrictions to the language.

It seems to me that the restrictions he's talking about adding to the language
are akin to making JS closer to Java, not closer to Haskell. Those similar
restrictions - in Java - make extending an existing library much more
difficult since you can't do things like add methods to an existing
class/object; that method has to exist elsewhere & take the object you're
extending as a parameter. This isn't an issue in Haskell since functions don't
exist on an object, but are defined outside the types & operate on them.

~~~
jxcole
Of course I have never programmed in Haskell, so perhaps I am showing my
ignorance, but my impression of Haskell is that it has all of the type
restrictions of java plus many, many more. My point is that a language like
Haskell (or Java, take your pick), can still have easy to use libraries
written for it.

Sure, you can't change the methods of a class has at run time. Who cares? Like
I said you can just create an object wrapper, sometimes called a decorator if
you are into design patterns, that has all of the methods of the original
object plus a few more (or even a few less, doesn't matter). This gives you
all of the functions of the original object plus more, just like modifying a
class at runtime does. Possible in Java, possible in Haskell, possible even in
JavaScript.

The only difference is that you have to explicitly call into the wrapper
classes. You can't expect objects that you instantiate from outside your
library to have these methods.

But again, who cares. If you want to use the cool new library functions, use
them. Otherwise don't.

Specific example: if we are talking about jquery, you can't expect
document.GetElementById('foo') to have special jquery functions. But you can
expect $('#foo') to have them, which is the same thing so you really have
nothing to complain about.

~~~
esmooov
I think Jeremy's real point is that Javascript is an entirely different beast
than Haskell or Java or Ruby. Why? Javascript depends on a free and open code
environment to get around the fact that the actual language's development
moves glacially, you have no control of the deploy environment (unless you are
a browser developer or are working in node) and it is not easy to manage large
projects (inclusion and namespacing features are lacking or limited in JS). In
fact, the only feature that allows JS to keep up at all with these other
languages is that it tells its developers "Look, I don't have a lot of fancy
features and I haven't really changed in about a decade, but I'm entirely
open. Hack and abuse me at your pleasure, codify me if you must, I'll take it.
I always do."

None of the proposed object-lockdown would _prevent_ anything. You could use
decorators, you could use an adapter, hell you could rewrite or fork the
useful library and take out the object-locks. But all of those introduce the
very overhead that JS benefits from avoiding. I mean compare the size of
"Javascript Pattern" to the GOF book. What's more, languages like Java are
written with a sensitivity toward design patterning, Haskell has robust
types/interfaces. Javascript just has a big empty box, prototypes and
closures. (This is an exaggeration but if you declaim it loudly enough you
will get a chuckle.)

------
reissbaker
I'm not sure where the opposition to private is coming from, outside of being
anti-additional-syntax. _Private variables already exist in Javascript._
They're just inefficient, because they mean that any of an object's instance
methods that reference them have to be declared inside of the class's
constructor function, instead of on the prototype.

Private variables may be accessible outside of classes in Ruby -- but they
already aren't in JS. And JS has extremely strong encapsulation through
scoping and closures, so arguments against encapsulation based on the
"language grain" fall a little flat for me. If an explicit private keyword
enables optimization of existing functionality, then why not have one?

------
gwern
> The freedom of having every object and every property be configurable,
> settable, introspectable, readable and writable, at least at the language
> level, is worth the trade off. If we add const, private, and other lock-down
> syntax, or make class properties private by default (shudder), I guarantee
> you that many potential innovative libraries that otherwise might spring up
> will never even be conceived, and frustrating situations that could have
> otherwise been solved by a quick patch will instead require convoluted work-
> arounds.

If you say so.

------
DrHankPym
I've been asking a lot of dumb questions today, so here's another: Do we have
any decent tools to measure memory usage / allocation when running a
Javascript program?

Once we start introducing these data structures we will have to figure out
actual memory storing (16bit? 32bit? 64bit?) which obviously introduces
another layer of complexity to "standardizing".

------
gisenberg
I think my biggest problem with the "if you don't want X to happen, then don't
do X" statement is that it only makes sense in the context of working as an
individual who controls all possible moving parts. It doesn't make sense (at
least, for me) in the context of a team.

~~~
erichocean
I've noticed that people are always trying to outsource code review to the
computer.

In my experience, no compiler is sufficiently intelligent to outsource this
to. And if you have to review the code anyway (and you do), enforcing coding
conventions is the least of your problems.

------
ruethewhirled
Doesn't seem like many people are considering the "security" benefits of
having private, constant and frozen.

Being able to freeze an object to prevent anything modifying it would be
useful for preventing 3rd party scripts you include on your site from deleting
or modifying your code's behavior.

~~~
knieveltech
So is proper namespacing.

~~~
ruethewhirled
Having thought about what you meant... Even with namespacing you still have a
global object that can be maliciously overridden or modified

~~~
knieveltech
If an attacker is in a position to make malicious modifications 1) You've got
a larger problem than optional language features on your hand and 2) locking
down a few properties (or the entire object) isn't going to save you.

~~~
ruethewhirled
From your example below: think of one of those ad network scripts (or any
other 3rd party script you include on your page) you have no control over what
that code is doing. It could override any of your global objects

~~~
knieveltech
This is accurate regardless of language features. You can't control 3rd party
code. Using generic object names greatly increases the odds that at some point
you're going to run into a namespace collision and something important will be
overwritten. Proper object namespacing your objects vastly decreases the odds
of this happening with benign 3rd party scripts, no additional language
features required.

------
angersock
From the article: ""private" does not add anything new to a property. If you
don't want the property to be used outside of the class ... don't use the
property outside of the class.

"const" does not add anything new to a variable. If you don't want to change
the value of a variable ... don't change the value of the variable.

"freeze" does not add anything new to an object. If you don't want to change
the shape of an object ... don't change the shape of the object. "

Now, having started to dabble a little in Rails and Node--and hence getting
exposure to Ruby and JS--I do have respect for a lot of the interesting things
you can do in those languages.

That said, I've also got a experience dealing with libraries and software
engineering on various sized projects, and I'm sensing a pattern here.

It seems like good practices (encapsulation, static typing, etc.) are being
ignored because they get in the way of "free programming". Now, is this
actually an accepted attitude in the web development world, or are these
people actively promoting terrible design practices?

I understand that programming routines for web pages and the like is not the
same as for thick-client applications, but is the use of your library by other
people through an interface or namespace collisions really not a large
concern?

------
ldar15
_The recent JavaScript renaissance that we're all enjoying owes debts to
JavaScript's foresight as a "free", dynamic language._

Bollocks. If javascript wasn't the language of browsers, nobody would use it.
Its got nothing to do with javascripts awesomeness. Indeed, that it took so
long for the community (or in this case Mozilla and Google) to finally say
"fuck it, this is the shitbag we're stuck with so at least lets make it
faster", just tells me how much they wanted something else to be the standard.

The only argument for NodeJs etc is that programmers can code the same
language on client and server. Was there some "foresight" that made javascript
the language of browsers? No.

That said, why fuck with it? There are ways to encapsulate fields and methods
in javascript. There are also ways to get around it. Just as there are ways to
get around private and const in C++.

If private and const really float your boat use GWT.

