The Tragedy of the Common Lisp, or, Why Large Languages Explode (was: revive let blocks)
Good points, Mark.
There are two better ways forward that I see:
-
Separate forms and make them compose well. Instead of let (x=y){z} and the grammatically unsound let (x=y)x*x from ES4, given let in ES6, and do expressions in ES7, declare victory and use
do { let x = y; z }
. -
Sweet.js (sweetjs.org), hygienic macros for JS, with syntax-case-strength matching and enforestation magic. sweetjs.org/doc/main/sweet.html
We try to follow (1) in TC39. It is why we didn't rush the ?. "null-soaking" operator in. I suspect that (2) deserves a look in about a year, but welcome thoughts from Tim Disney et al (@natefaubion @jlongster).
Very well said Mark! You've basically articulated what I've been thinking for a few years now as someone lurking amongst these lists afraid to speak up. Often times I've seen people's questions or criticisms get shut down with a link to lmgtfy often followed by an emoticon or two, which doesn't make posting in these lists seem very inviting.
I really really love JS (it's so fun!), and while there are many features in ES6 that I think are great (such as classes, modules, and import syntax) there are things that quite frankly scare me quite a bit. Such examples include destructuring and arrow functions, which make sense when used in simple use cases but I find confusing to interpret when reading someone else's code due to their terseness.
But you know what? I can live with ES6. I did enjoy, while it lasted, the comfort in understanding 99% of JS due to its smallness. But I don't mind learning a few more new concepts derived from other languages if it means I can become better at both reading and writing code. But with ES6 pretty much set in stone, ES7 will be the next round of discussions. So like you said Mark, I think more of us (including myself) shouldn't be afraid to share our panic. It's extremely easy to agree with someone on something, but I think more often than not those who disagree likely hesitate in contributing to the conversation.
First of all, brilliant post Mark.
As a community, we need more of a shared sense of panic about the size
that ES6 has already grown to. Ideally, that panic should increase, not decrease, with further growth from here as our size approaches the point of no return.
As a community, we do - if you look at HackerNews or Reddit or
StackOverflow people are constantly hating on JS getting larger. Features
like classes and let
are very often criticised and often languages that
did not add these features and are considered 'well designed' are given in
comparison (Python's lack of block scoping for instance).
This is a mailing list comprised of people who typically have a much better understanding of the language and its corners than most (even professional) developers have (and dare I say, are interested in or care about having). With ES6 the language already got a lot bigger and I'd argue that it's now harder to learn the whole. The tradeoffs were worthwhile but it's definitely an issue.
It's easy to forget here what traps the average user might fall into, and it's easy to forget what they care about and what confuses them.
Fwiw, there are examples of big languages that are well liked, the "canonical" example of a big but very well liked (and well designed imho) language is C#. It has a lot of cruft now (delegates and events, array covariance etc) but it is still a very well liked language in general.
I've worked with sweet.js a lot, and someone pointed this email out to me. I can't agree more. I love all the ES6 features, and some of ES7, but looking at some of the future ES7 stuff (like decorators, etc) makes me wonder what a "finished" JavaScript will look like. I'm not bashing on decorators specifically, just that every new feature (like classes) seems to require rethinking of so many other things (how do we wrap class methods?) that we didn't have to do before.
I think Scheme and Lisp have had the most success as small languages, particularly because of macros. Users weren't just stuck with a small language, they could extend it when they really needed to.
I think JavaScript needs macros. It's the hardest language to change,
and yet one of the most used languages. Macros would let it thrive and
new features like await/async could be implemented by the community in
a matter of weeks. Babel has already pioneered an environment where
new ES7/8 features are available instantly to everybody, but the
problem is that you have to compile, and nothing is composable. I
can't release a new async library on npm that implements CSP channels
and provides a go
form which is new syntax for firing off a
blockable process.
Clojure was able to release core.async, precisely the above channel implementation, as a library that provides that new form. Immediately people could start using it without having to update Clojure at all.
Of course, there's tons of technical problems here. sweet.js is cool but you still have to compile, so macros need to be native. sweet.js is also a bit slow at the moment. I don't know if it's possible for hygienic macros to be fast enough (Tim Disney, creator of sweet.js, would need to answer that). It may be possible to use sweet.js's pattern matching mechanism but avoid hygiene altogether for speed (and provide gensym capability).
I thing someone should take a serious a look at this, though. TC39 would certainly not have to hand-hold JS quite as much.
I like Mark's post too, and if I might ...
Features like classes and
let
are very often criticised and often
languages that did not add these features and are considered 'well designed' are given in comparison (Python's lack of block scoping for instance).
thing is, ES6 brought in many things that took years to explain in the "JS
way" and when finally developers started knowing and appreciating
prototypal
inheritance and started understanding the var
behavior, to
name just few, "we" started promoting ES6 as the universal problem solver
for every dev so that let
is the new var
(most developers still don't
even know what does it mean) and const
is the better let
and class
finally is in the language, something that desugar anyway to prototypal
inheritance, something developers still need to understand.
So I agree we should really stop going fancy with syntax, probably think about sweet.js like approches, and fix all the things that will need to be fixed in ES6, improving and finalizing classes bringing in composition like it has always been possible before through prototypal inheritance. I really do hope traits will be highly prioritized and binary/typed data/shapes too 'cause I don't think JS needs many more changes as it is today.
Just my lil'rant and keep up the good work.
Best
I don't think JS needs many more changes as it is today.
I mean it does, but mostly on browsers land, not in its core
It seem semi-obligatory at this point to cite "Growing a Language", by Guy Steele. www.youtube.com/watch?v=_ahvzDzKdB0 Transcript at www.cs.virginia.edu/~evans/cs655/readings/steele.pdf (if you must).
I tend to agree with the idea that at this point we need means to grow syntax rather than new syntax. Similarly, JavaScript needs means to add new lightweight types rather than more lightweight types.
Once that is done, operator overloading would complete the circle, and allow the community to grow further lightweight types and syntactic forms as they please. --scott
On 18 June 2015 at 19:26, Benjamin Gruenbaum <benjamingr at gmail.com> wrote:
This is a mailing list comprised of people who typically have a much better understanding of the language and its corners than most (even professional) developers have (and dare I say, are interested in or care about having). With ES6 the language already got a lot bigger and I'd argue that it's now harder to learn the whole. The tradeoffs were worthwhile but it's definitely an issue.
I dare say that at this point Allen probably is the only person in the world who actually fully knows and understands the complete language. I won't hesitate to admit that I don't. ;)
Preach it, brother!
I'd like to jump on the bandwagon of Mark's concern about the death-of-a-thousand-cuts phenomenon.
It is far too easy to make a bunch of small additions, each of which is individually worthy and justifiable, that collectively add up to a sum total that is not so worthy or justifiable. It's particularly easy when we have a process which considers each proposed change or addition in isolation, considering it individually on its own merits as if it was all that we were doing. There's lots of good stuff in ES6, but the overall mass and complexity of the thing still makes me a little queasy.
I've been observing the TC39 process for about six months now, without plunging into the discussion very deeply yet (still getting the lay of the land, as it were). One thing I find striking is the number of proposals being floated that seem to be based on "this could be useful" or "some other language I like does this" or "I think it's cool" or "I wish I could code like this instead of like that". In contrast, I see relatively few people responding to these proposals with questions like "do developers really need this?" or "what actual problem does this solve?". I see relatively few advocates for minimalism as a virtue per se, minimalism being a corrective to the kinds of bloat that arises from a horde of wafer thin changes.
Chip
On Jun 18, 2015, at 7:37 AM, Mark S. Miller <erights at google.com<mailto:erights at google.com>> wrote:
On Wed, Jun 17, 2015 at 7:27 PM, Kyle Simpson <getify at gmail.com<mailto:getify at gmail.com>> wrote:
I'd like to ask if there's anyone on TC39 that would be willing to champion a proposal to add the let-block (let-statement) syntax?
I am not. Further, if anyone were, I would work to kill it. Here's why.
The Algol, Smalltalk, Pascal, and early Scheme languages were prized for being small and beautiful. The early C and JavaScript languages were justifiably criticized for many things, and rarely mistaken for a language that was generally beautiful. But they were small, and this aspect was properly and widely appreciated. When a language is small, our appreciation of it is often driven by the sense "I can learn the whole thing, and then I will have a mastery of it", and later "I know the whole thing. I love the fact that there are no corners I don't know." For C and JavaScript, few who thought they knew the whole thing actually did -- the details were actually fiendishly complex. Nevertheless, this sense drove much of the satisfaction with everyday usage.
The esthetic of smallness of JS lasted through ES5. I participated heavily in both ES5 and ES6 and in both cases I am proud of my contributions. ES6 is much larger, but nevertheless it is a much better language. Given where we started, we could not have achieved these gains in the utility of JS without such an increase in size. I do not regret most of the additions that grew ES5 to ES6. For many of these, had we the ES6 standards process to do over again, I would likely make similar additions.
But each of the additions that grew ES5 into ES6 had to pass a very high bar. Psychologically, this made sense to all of us because we were starting from a language, ES5, whose smallness we could still appreciate. When a language is small, every additional feature is viscerally felt as a significant percentage increase in the size of the language. The specific benefits of a feature are always visible to its advocates. But for a small language, a new feature's general costs in added complexity are also still visible to everyone.
Once a language gets beyond a certain complexity --- say LaTeX, Common Lisp, C++, PL/1, modern Java --- the experience of programming in it is more like carving out a subset of features for one's personal use out of what seems like an infinite sea of features, most of which we become resigned to never learning. Once a language feels infinite, the specific benefits of a new feature are still apparent. But the general costs in added complexity are no longer apparent. They are no longer felt by those discussing the new feature. Infinity + 1 === Infinity. Even aLargeNumber + 1 === approximatelyAsLargeANumber. This is the death of a thousand cuts that causes these monstrosities to grow without bound.
So please, I beg all of you, when considering a new feature, please apply a higher bar than "Wouldn't it be nice if we could also write it this way?". I believe that ES6 is in that middle territory where unrestrained growth is not yet inevitable, but only if we all restrain each other with high standards for any proposed new feature. As a community, we need more of a shared sense of panic about the size that ES6 has already grown to. Ideally, that panic should increase, not decrease, with further growth from here as our size approaches the point of no return.
I suspect that (2) deserves a look in about a year, but welcome thoughts
from Tim Disney et al (@natefaubion @jlongster).
Yep, that sounds about right.
Sweet.js design is all about dealing with use-cases like this; start with a small core and then grow the syntax needed for your domain.
If anyone is curious here's the macro that implements the proposed extra let form (asuming I understand it right):
let let = macro {
rule {
( $($var:ident = $init:expr) (,) ...) {
$body ...
}
} => {
{
let $($var = $init) (,) ...
$body ...
}
}
}
Of course, there's tons of technical problems here. sweet.js is cool but you still have to compile, so macros need to be native.
Some better tooling would help the dev experience but yeah native would be the dream.
sweet.js is also a bit slow at the moment. I don't know if it's possible for hygienic macros to be fast enough (Tim Disney, creator of sweet.js, would need to answer that). It may be possible to use sweet.js's pattern matching mechanism but avoid hygiene altogether for speed (and provide gensym capability).
Hygiene isn't actually the performance problem. It's just that sweet.js started out as a research prototype and I've never taken the time to step back and really do the right engineering to make it better. I have a long list of things that will hopefully make things way better and now that I'm almost done with my dissertation I hope to start addressing them soon.
On Jun 18, 2015, at 12:18 PM, Andreas Rossberg wrote:
On 18 June 2015 at 19:26, Benjamin Gruenbaum <benjamingr at gmail.com> wrote: This is a mailing list comprised of people who typically have a much better understanding of the language and its corners than most (even professional) developers have (and dare I say, are interested in or care about having). With ES6 the language already got a lot bigger and I'd argue that it's now harder to learn the whole. The tradeoffs were worthwhile but it's definitely an issue.
I dare say that at this point Allen probably is the only person in the world who actually fully knows and understands the complete language. I won't hesitate to admit that I don't. ;)
And I occasionally have to go and look up details.
And I occasionally have to go and look up details.
You know nothing Allen Wirfs-Brock (cit)
This is just a heads up for context that someone published a link to Mark's post in HN here: news.ycombinator.com/item?id=9738866 in case we get any more new people posting in the thread.
Features like classes and
let
are very often criticised and often
languages that did not add these features and are considered 'well designed' are given in comparison (Python's lack of block scoping for instance).
thing is, ES6 brought in many things that took years to explain in the "JS way" and when finally developers started knowing and appreciating
prototypal
inheritance and started understanding thevar
behavior, to name just few, "we" started promoting ES6 as the universal problem solver for every dev so thatlet
is the newvar
(most developers still don't even know what does it mean) andconst
is the betterlet
andclass
finally is in the language, something that desugar anyway to prototypal inheritance, something developers still need to understand.
I completely agree - I think that classes and let as ways to standardise the best practice way of something most people are already doing. This is a noble and very important thing that really helps. By letting wisdom of the masses show us what people need and letting user-land solutions spearhead progress and then specifying the parts that work is an excellent approach - having a TC in charge is really nice and ensures vision and order. The reason I'm trying to get more involved in the process is because I like the way things are heading and the discussions held (and I'm learning a lot).
I don't know about additional syntax - but the fact the bar is raised is very important.
If people are unable to internalize the whole language, then surely we need a way to remove cruft and idiosyncracies in it, lest the language stagnate beyond repair.
Removing var, typeof, exotic objects, function declarations, IsNaN, ==, enumerable properties, are just a few examples of things we should not be frightened to talk about.
While I don't personally see a need for the proposed let syntax, I think that concerns about the language growing uncontrollably should be directed at its apparent lack of deprecation strategy, rather than shutting down discussion of new ideas that might help us write better programs.
Just my 2p.
I don't think anyone is "frightened" about removing these things. The TC
has a commitment not to "break the internet", by removing something like
var
or typeof
you're disabling billions of people who are using the
internet - it would very much literally "break the internet". Even if the
TC unanimously votes on removing 'var' - this is not something browser
vendors would do anyway.
This issue has been discussed on the list several times before and even the
modest attempt to fix typeof null
failed when it was attempted. Here is
some discussion about it esdiscuss.org/topic/typeof-null
The way forward is pretty much to avoid features like with
for the most
part, understand older code but gradually write newer code. Any breaking
changes to the language require extensive research which will likely
conclude in not making the change (like var
) anyway.
Note that strict mode already fixes a lot of things (quirkiness of arguments, with, non-lexical scope, globals, etc). Classes have safe defaults (non enumerability of properties), for... of loops typically do the correct thing based on the new iteration protocol and so on.
Greg McLeod <cleod9 at gmail.com> wrote:
I really really love JS (it's so fun!), and while there are many features
in ES6 that I think are great (such as classes, modules, and import syntax) there are things that quite frankly scare me quite a bit. Such examples include destructuring and arrow functions, which make sense when used in simple use cases but I find confusing to interpret when reading someone else's code due to their terseness.
I think the difference between your list and mine exemplifies the tragedy
of the commons as so well described by Mark. Although we both share a
liking for modules and imports, my favorite ES6 feature is the arrow
functions, with destructuring near the top. The very bottom of my list,
the only one I really, really wish n not been included is class
.
Covering the desires of both users like you and users like me is what can so easily leaf to bloat.
On 19 June 2015 at 10:06, Alexander Jones <alex at weej.com> wrote:
If people are unable to internalize the whole language, then surely we need a way to remove cruft and idiosyncracies in it, lest the language stagnate beyond repair.
Removing var, typeof, exotic objects, function declarations, IsNaN, ==, enumerable properties, are just a few examples of things we should not be frightened to talk about.
While I don't personally see a need for the proposed let syntax, I think that concerns about the language growing uncontrollably should be directed at its apparent lack of deprecation strategy, rather than shutting down discussion of new ideas that might help us write better programs.
While I agree that the impossibility of deprecating features is a problem (without a solution in JS), it's also fair to say that deprecation doesn't really work or help. Take C++ as the obvious example. They do deprecate occasionally, with difficulties. Yet the language had already blown complexity out of any sane proportion 25 years ago. Let alone today. Not a chance that there is a single person who even remotely understands the full language, and there probably hasn't been one for 3 decades at least.
Deprecation doesn't solve the problem because new cruft typically gets added orders of magnitude faster than old cruft can ever be removed. That is true for almost all production languages. Because it's so much easier to add stuff.
Thus, the only way to keep a language small (if at all) is being extra careful about adding features. Just about any terrible feature can be justified by "use cases", but that's insufficient reason to add it. Especially "convenience" features are a slippery slope. (I could make a list of ES6 additions that already violate this principle.)
The art in language design isn't what to add, but what to leave out.
An interesting wrinkle in language design has been the rise of
sophisticated linting and style tools like jscs
. If you wish to
deprecate var
for instance, it is straightforward to write a jscs module
to enforce that. Further, several large communities (node, wikipedia, etc)
have published jscs "presets" that effectively define the subset of the
language they use.
So in a meaningful way we are getting the tools to voluntarily deprecate features in a community-driven way. Certain quirks may always exist in the spec (although perhaps more and more they will migrate to compatibility appendixes), but can be effectively ignored for communities opting in to jscs presets.
I note that certain ES6 features have also been written specifically to
allow opt-in to sane behavior. For example, a SaneArray
subclass of
Array is often discussed here. Use of SaneArray instead of stock Array
could also be enforced by jscs-like tools. (Although this means giving up
Array literal syntax? So there's still a bit of awkwardness. And API
boundaries are tricky. Future work!)
Anyway, I look forward to a continued process of community-driven feature deprecation, and hope that we will continue to look for ways in ES7 to allow further opt-in fixes to our warts. (I also look forward to continued development of interesting rule sets and analyses in jscs and similar tools to shave off warts.)
I do not share Mark's view. Contra his sentiment, I was using the "small" version of JS for many years and noted that most non-trivial uses required finding or building a library. That choice of library (which exist to fill in platform and language deficiencies) leads to a a split in common use that's just as pernicious as "choosing a subset".
Writing JS in the large continues to need more help.
It sounds like you are advocating for a larger standard library in JS. I think many on this thread are focusing on whether more syntax features should be added.
On Jun 19, 2015, at 10:29 AM, Alex Russell wrote:
I do not share Mark's view. Contra his sentiment, I was using the "small" version of JS for many years and noted that most non-trivial uses required finding or building a library. That choice of library (which exist to fill in platform and language deficiencies) leads to a a split in common use that's just as pernicious as "choosing a subset".
Writing JS in the large continues to need more help.
I agree with parts of both Mark's and Alex's positions.
It isn't clear that any "small" language has ever seen the sort of industry dominance that languages like C/C++ achieved. I'd even argue that the an unwilling (or inability) to grow was one of the reasons that (Pascal and Smalltalk) both sputtered out after some initial success. Pragmatic growth is probably essential for achieving and maintaining broad adoption.
On the other hand, curation of language growth is really important. Not every good idea can be fit into a language and not evert seemingly valuable features has long term utility or durability.
ES needs to evolve more rapidly than once every 5-15 years. The yearly update plan is good, but that doesn't mean we should be rushing proposals (particularly complex ones) through the process in order to catch the next yearly release. Bake time is good. There are numerous ES6 features that are much better because their design had a chance to evolve over a a two or three year period.
This isn't a contest to see who can or can't get their favorite feature into the language. Nobody should take it personally if their good idea doesn't make it. I've probably had dozens of of really good ;-) ideas for making ES better that haven't made it into the language.
On Fri, Jun 19, 2015 at 12:29 PM, Alex Russell <slightlyoff at google.com> wrote:
I do not share Mark's view. Contra his sentiment, I was using the "small" version of JS for many years and noted that most non-trivial uses required finding or building a library. That choice of library (which exist to fill in platform and language deficiencies) leads to a a split in common use that's just as pernicious as "choosing a subset".
Writing JS in the large continues to need more help.
On Fri, Jun 19, 2015 at 10:42 AM, Mark Volkmann <r.mark.volkmann at gmail.com>
wrote:
It sounds like you are advocating for a larger standard library in JS. I think many on this thread are focusing on whether more syntax features should be added.
First, from many arguments with Alex, I am indeed confident that Alex and I have different views about these matters.
In my post, I definitely meant more than syntax, but I also agree that the force of my point gets weaker as we move from core language to standardizing libraries. The overall standard language can be seen as consisting of these major parts:
- fundamental syntax -- the special forms that cannot faithfully be explained by local expansion to other syntax
- semantic state -- the state than computation manipulates
- kernel builtins -- built in library providing functionality that, if it were absent, could not be provided instead by user code.
- intrinsics -- libraries that semantic state or kernel builtins depend on. For example, with Proxies, one might be able to do Array in user code. But other kernel builtins already have a dependency on Array specifically, giving it a privileged position over any replacement.
- syntactic sugar -- the syntax that can be explained by local expansion to fundamental syntax.
- global convenience libraries -- could be implemented by unprivileged user code, but given standard global naming paths in the primordial global namespace.
- standard convenient library modules
I have listed these in order, according to my sense of the costs of growth and the urgency for minimalism. For all of these we still need to exercise discipline. But it is only for the last one that we should consider growth of absolute size to be unbounded; restricting ourselves only to the rate of growth as we wait for candidates to prove themselves first by the de facto process. Ideally, TC39 should stop being the bottleneck on the last bullet anyway, as external de facto and de jure processes should be perfectly capable of independently arguing about and evolving standard convenience modules.
In all of the examples I mentioned there are other, more predictable alternatives already in the language. Do we really expect JavaScript programmers in 2025 to remember to use Number.isNaN instead of isNaN? I really don't understand why people think "use strict" was OK to pull off, but further breaking-change evolutions of the language are not.
ES needs to evolve more rapidly than once every 5-15 years. The yearly update plan is good, but that doesn't mean we should be rushing proposals (particularly complex ones) through the process in order to catch the next yearly release. Bake time is good. There are numerous ES6 features that are much better because their design had a chance to evolve over a a two or three year period.
I think the yearly release plan encourages too much "feature racing".
"use strict" was only a breaking change regarding ES3 code that coincidentally happened to use exactly this literal string as a do-nothing expression statement in exactly this position. In all of the web, we have not run across a single incident of this happening accidentally.
For the record, not only have we successfully deprecated one feature, we have even wounded it sufficiently that I expect most of us will outlive it:
function.caller, function.arguments, arguments.caller,
arguments.callee.
But note the effort it took to wound it and the time it is taking to die.
Indeed Mark.
It took some of us longer to unwind those features out of our codebase than others.
One of my biggest concerns in switching to the "yearly" numbering system is the same as Allen & Kevin: there will be pressure to ship new features every year (as if we're a software company that wants to get our users on the upgrade treadmill).
Insofar as breaking changes, "use strict" in E5 was basically hitting the low-hanging fruit. Now things get much more tricky. As has been endlessly stated, you can't break the web. Therefore, I would anticipate future versions of this spec to continue to be what they have been in the past: mostly additive, except where clarifications are required. Anything else is incredibly disruptive - much more so than the switch from IPv4 to IPv6 and we see how long that has taken - and only under the threat of running out of addresses. JS faces no such threat.
On Jun 19, 2015, at 11:24 AM, Kevin Smith wrote:
ES needs to evolve more rapidly than once every 5-15 years. The yearly update plan is good, but that doesn't mean we should be rushing proposals (particularly complex ones) through the process in order to catch the next yearly release. Bake time is good. There are numerous ES6 features that are much better because their design had a chance to evolve over a a two or three year period.
I think the yearly release plan encourages too much "feature racing".
It can and we are probably already seeing some signs of that. But it doesn't have too, if we are disciplined within TC39 collectively develop the understanding that yearly release is more about opening doors and closing them.
Regardless, I think that long term thinking is really important for TC39 participants. A language standards body is usually not the place to get immediate solutions to immediate problems.
On Jun 19, 2015, at 2:53 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
On Jun 19, 2015, at 11:24 AM, Kevin Smith wrote:
ES needs to evolve more rapidly than once every 5-15 years. The yearly update plan is good, but that doesn't mean we should be rushing proposals (particularly complex ones) through the process in order to catch the next yearly release. Bake time is good. There are numerous ES6 features that are much better because their design had a chance to evolve over a a two or three year period.
I think the yearly release plan encourages too much "feature racing".
It can and we are probably already seeing some signs of that. But it doesn't have too, if we are disciplined within TC39 collectively develop the understanding that yearly release is more about opening doors and closing them.
This could make a big difference, out here in user land, to alleviate the pain of waiting for simpler language features like Template Strings.
—ravi
From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Kevin Smith
I think the yearly release plan encourages too much "feature racing".
I would state it somewhat differently. I think it encourages too much "feature marketing". That is, there are a number of complicated proposals which are often presented at conferences as "ES7" (or named as such by Babel). In reality, very few proposals are likely to make it to stage 4 ( = two tests-passing shipping implementations) in the relatively few months we have left. People are marketing their feature as something that is racing toward the finish line, even though in reality it is far from it.
My expectation is that this will self-correct. I don't expect TC39 to be any less deliberate than usual; moderately complex features will take a couple years or more to bake. So, as the champions of those features get quickly embarrassed by watching the ES2016 spec (and probably the ES2017 spec) get published without their feature, they'll modulate their marketing to something more reasonable. Then it will feel less like a race and more like the deliberate process it always has been.
Someone just brought news.ycombinator.com/item?id=9742823 to my attention. It says:
I like the author’s remarks and philosophy about keeping JavaScript small, but I thought the opening was remarkably uncharitable. The specific person and the specific feature are quite irrelevant to the point he’s making here.
I am left with some admiration for his goals, but also a great deal of trepidation about ever suggesting anything or even talking about JavScript.next. Will I be the next one called out by name if I make the mistake of asking whether traits might be a good addition to JavaScript?
I agree completely, and I fully apologize. Starting the thread this way was inappropriate, at least without some mitigating text which I did not think to add. I like the fact that we are all civil to each other here and try to keep the environment welcoming and friendly. Please no one take my message as precedent in the other direction.
On Fri, Jun 19, 2015 at 7:23 AM, Scott Sauyet <scott at sauyet.com> wrote: I think the difference between your list and mine exemplifies the tragedy of the commons as so well described by Mark. Although we both share a liking for modules and imports, my favorite ES6 feature is the arrow functions, with destructuring near the top. The very bottom of my list, the only one I really, really wish n not been included is
class
.Covering the desires of both users like you and users like me is what can so easily leaf to bloat.
I think we're actually on the same page in terms of where a lot of the problems lie in these discussions (though personally I've at least conceded to ES6 at this point, since for me the core issue is more about interpreting other people's code than it is about using it myself where I can control its readability). It's probably not possible to add something to a language that everyone likes, so the only option seems to be compromise. In a way that's kind of a double-edged sword, where both parties might benefit individually but at the cost of inhibited conversation between the opposing sides (e.g. "i don't mind you getting X so long as I can Y"). But I imagine as more people pick up ES6 it might become clearer what the average dev is getting the most benefit from, and those areas might be worth putting extra attention.
On Fri, Jun 19, 2015 at 8:18 PM, Mark S. Miller <erights at google.com> wrote:
Someone just brought news.ycombinator.com/item?id=9742823 to my attention. It says:
I agree completely, and I fully apologize. Starting the thread this way was inappropriate, at least without some mitigating text which I did not think to add. I like the fact that we are all civil to each other here and try to keep the environment welcoming and friendly. Please no one take my message as precedent in the other direction.
Despite your opening I think you still fired up a much needed conversation. This is the most critical thread I've read in awhile, and in a way it feels a bit like a post-mortem for the recent release. Speaking of which, a retrospective thread might be a good thing to have on a regular basis after any ECMAScript release to get people's lingering thoughts out in the open before moving on.
I agree completely, and I fully apologize. Starting the thread this way
was inappropriate, at least without some mitigating text which I did not think to add. I like the fact that we are all civil to each other here and try to keep the environment welcoming and friendly. Please no one take my message as precedent in the other direction.
I think what that HN thread is missing is that you and Kyle know each other from before and interacted before and you knew he would not take personal offense in it or think you don't appreciate his contribution efforts to the standard.
I agree completely, and I fully apologize. Starting the thread this way was inappropriate, at least without some mitigating text which I did not think to add. I like the fact that we are all civil to each other here and try to keep the environment welcoming and friendly. Please no one take my message as precedent in the other direction.
I think what that HN thread is missing is that you and Kyle know each other from before and interacted before and you knew he would not take personal offense in it or think you don't appreciate his contribution efforts to the standard.
"Kill" seemed too directed at first and was off-putting, especially since there are a lot of post-ES6 proposals floating about and none of them received the same sort of strong pushpack. It's not as if there was evidence that the proposal was intentionally bad-faith, toxic or trolling. I appreciate Mark's reflective sentiments, and I also echo his general concerns of growing a language beyond its appropriate scope.
I believe small variations to existing features should have far less burden of "proof" than large features. It's a minor affordance for a particular style of coding with no other value proposition other than to assist in avoiding mistakes (the TDZ footgun specifically). I think that carries its own weight and then some. And further, I don't think small polishes are necessarily the subject of "death by a thousand papercuts", though I recognize they can lead to that if we're not judicious.
In any case, I won't push my proposal anymore. I just wanted to assert it was carefully considered beforehand.
In the spirit of "retrospective on ES6", my own concerns with ES6 are not in the small things (or even in the raw count of features added), but actually in some large things. There were major features (such as class
) added in ES6 that I continue to have strong reservations about, not just in themselves but in how we're seeing them already in post-ES6 act as magnets for several other feature requests. I'm not trying to re-litigate class
by any means -- it's a done deal -- but simply pointing out that a large feature like that is, I think, more susceptible to lead to feature bloating than tiny syntax tweaks.
I respect and appreciate the difficult work it takes to make these decisions. I hope the positive spirit of this thread carries over into careful consideration of the other post-ES6 proposals, even and especially the ones that have garnered lots of excitement and are already being talked about as if they're "done", but which may not in the long run be best for JS.
While I am also concerned with the problem of ever-expanding languages because the larger they grow, the harder they are to learn, and the harder it is to read someone else's code which uses unfamiliar features, there are other issues that are equally important.
I find the most unappreciated feature of a language is the list of things it can't do. For a bit of background, my first program was written in machine language, and after struggling with it, the instructor introduced the class to a wonderful tool: assembler language. Sufficient to say, I know about languages with built in footguns.
The advantage of having a language that doesn't allow certain things is that you don't have to worry about them when you are debugging or reviewing a program. Memory safety is high on the list of useful features which JS has. Another very valuable feature is the ability to limit what a piece of code can do before you invoke it. In the JS arena, this kind of limitation allows web sites which give their users security assurances to run arbitrary JS provided by advertisers. ES2015 has a number of features to support this usage, but because of the need to not "break the web", they are a bit delicate to use.
It would be good to include a list of the things you can't do in the language specification so failures in this area are clearly bugs in either the implementation or the specification. I would suggest for JS that this list include the things required for confining a piece of JS code running within a larger environment, like a web page to keep it from doing all the things the web page can do.
Cheers - Bill
Bill Frantz | Ham radio contesting is a | Periwinkle (408)356-8506 | contact sport. | 16345 Englewood Ave www.pwpconsult.com | - Ken Widelitz K6LA / VY2TT | Los Gatos, CA 95032
On Sat, Jun 20, 2015 at 11:18 AM, Bill Frantz <frantz at pwpconsult.com> wrote:
While I am also concerned with the problem of ever-expanding languages because the larger they grow, the harder they are to learn, and the harder it is to read someone else's code which uses unfamiliar features, there are other issues that are equally important.
I find the most unappreciated feature of a language is the list of things it can't do. For a bit of background, my first program was written in machine language, and after struggling with it, the instructor introduced the class to a wonderful tool: assembler language. Sufficient to say, I know about languages with built in footguns.
The advantage of having a language that doesn't allow certain things is that you don't have to worry about them when you are debugging or reviewing a program. Memory safety is high on the list of useful features which JS has. Another very valuable feature is the ability to limit what a piece of code can do before you invoke it. In the JS arena, this kind of limitation allows web sites which give their users security assurances to run arbitrary JS provided by advertisers. ES2015 has a number of features to support this usage, but because of the need to not "break the web", they are a bit delicate to use.
It would be good to include a list of the things you can't do in the language specification so failures in this area are clearly bugs in either the implementation or the specification. I would suggest for JS that this list include the things required for confining a piece of JS code running within a larger environment, like a web page to keep it from doing all the things the web page can do.
Hi Bill, regarding the list of bullets
On Fri, Jun 19, 2015 at 11:12 AM, Mark S. Miller <erights at google.com> wrote:
- fundamental syntax -- the special forms that cannot faithfully be explained by local expansion to other syntax
- semantic state -- the state than computation manipulates
- kernel builtins -- built in library providing functionality that, if it were absent, could not be provided instead by user code.
- intrinsics -- libraries that semantic state or kernel builtins depend on. For example, with Proxies, one might be able to do Array in user code. But other kernel builtins already have a dependency on Array specifically, giving it a privileged position over any replacement.
- syntactic sugar -- the syntax that can be explained by local expansion to fundamental syntax.
- global convenience libraries -- could be implemented by unprivileged user code, but given standard global naming paths in the primordial global namespace.
- standard convenient library modules
your point is another reason to prioritize the first four bullets over the last three. To understand what can't be done requires a deep understanding of at least the first three and arguably the fourth. However, the last three bullets cannot have any effects on the inabilities provided by a language.
On Wed, Jun 17, 2015 at 7:27 PM, Kyle Simpson <getify at gmail.com> wrote:
I am not. Further, if anyone were, I would work to kill it. Here's why.
The Algol, Smalltalk, Pascal, and early Scheme languages were prized for being small and beautiful. The early C and JavaScript languages were justifiably criticized for many things, and rarely mistaken for a language that was generally beautiful. But they were small, and this aspect was properly and widely appreciated. When a language is small, our appreciation of it is often driven by the sense "I can learn the whole thing, and then I will have a mastery of it", and later "I know the whole thing. I love the fact that there are no corners I don't know." For C and JavaScript, few who thought they knew the whole thing actually did -- the details were actually fiendishly complex. Nevertheless, this sense drove much of the satisfaction with everyday usage.
The esthetic of smallness of JS lasted through ES5. I participated heavily in both ES5 and ES6 and in both cases I am proud of my contributions. ES6 is much larger, but nevertheless it is a much better language. Given where we started, we could not have achieved these gains in the utility of JS without such an increase in size. I do not regret most of the additions that grew ES5 to ES6. For many of these, had we the ES6 standards process to do over again, I would likely make similar additions.
But each of the additions that grew ES5 into ES6 had to pass a very high bar. Psychologically, this made sense to all of us because we were starting from a language, ES5, whose smallness we could still appreciate. When a language is small, every additional feature is viscerally felt as a significant percentage increase in the size of the language. The specific benefits of a feature are always visible to its advocates. But for a small language, a new feature's general costs in added complexity are also still visible to everyone.
Once a language gets beyond a certain complexity --- say LaTeX, Common Lisp, C++, PL/1, modern Java --- the experience of programming in it is more like carving out a subset of features for one's personal use out of what seems like an infinite sea of features, most of which we become resigned to never learning. Once a language feels infinite, the specific benefits of a new feature are still apparent. But the general costs in added complexity are no longer apparent. They are no longer felt by those discussing the new feature. Infinity + 1 === Infinity. Even aLargeNumber + 1 === approximatelyAsLargeANumber. This is the death of a thousand cuts that causes these monstrosities to grow without bound.
So please, I beg all of you, when considering a new feature, please apply a higher bar than "Wouldn't it be nice if we could also write it this way?". I believe that ES6 is in that middle territory where unrestrained growth is not yet inevitable, but only if we all restrain each other with high standards for any proposed new feature. As a community, we need more of a shared sense of panic about the size that ES6 has already grown to. Ideally, that panic should increase, not decrease, with further growth from here as our size approaches the point of no return.