22 ms·
Future JavaScript: what is still missing?
- bcherny 8y agoAs an aside, I’m not seeing any novel features in this list. All of them seem to be borrowed from other languages (Swift, F#, Haskell, ...). With enough of this, at what point will all languages start to look identical (Youngme Moon calls this “homogeneous heterogeneity”)? And how often does a language come along that introduces something truly new, rather than porting an idea from another popular language?
- dmitriid 8y agoYou’ve got to have a solid base before you jump to innovating and introducing something “truly new”.
- macawfish 8y agoSlightly different angle... but for me, the special thing about Javascript is that it comes with a whole web browser. Being able to do the stuff those other languages can do in the browser makes me happy :) I especially like the pipe operator, even though I think the `|>` is kinda clunky asthetically.
- bcherny 8y agoSince everyone is coming from different language backgrounds, I wonder if it’s better to treat JS/WASM as a low-level compile target, and simply compile peoples’ language of choice to JS (OCaml via Bucklescript, Scala via ScalaJS, Haskell via PureScript, Clojure via ClojureScript, etc). That way you avoid bloating the core language with everyone’s pet features (I’d also love pipe syntax, but am not sure it belongs in JS core).
- int_19h 8y agoIn principle, it's a fine idea, if we started with something like wasm. But JS the language is already horribly bloated in many ways, so it's hard to justify avoiding new features on the basis of KISS - that ship has sailed a long time ago. (OTOH, note that nobody is proposing to add this sort of high-level stuff to wasm. That's because it's designed to be a compilation target, and it's actually good at it.)
- kristiandupont 8y agoWhy should every city have a theatre? Is there any reason to "leave features to others" if they make sense in your own language? The only issue I can come up with is that some language might die off because it doesn't have any unique features. But if that happens and the momentum is not enough to keep it alive, that doesn't seem like loss to me anyway.
- bcherny 8y agoI don’t know, it just feels like a bit of a boring world if every language looks the same, instead of prodding you to look at the world from a slightly different angle.
- baddox 8y agoI really don’t see this criticism. Yes, all of these features have existed in some form in prior languages. But I wouldn’t say that this makes JS “look like” Haskell.
- bcherny 8y agoAgreed. But if F#’s pipe operator makes it to Hack and JavaScript, null chaining makes it to C#, CoffeeScript, and JavaScript, value types make it to Haskell, Clojure, and JS, etc.. Eventually the overlap between different languages’ features grows larger.
- mbo 8y agoLike, I absolutely agree with you here. Languages are starting to stabilise when it comes to syntax, features are getting cross pollinated from other languages faster, etc. I think it's wonderful. Developers can move between languages interchangeably, teaching burden is reduced, languages aren't dismissed because they lack feature X.
- bcherny 8y agoThat’s a valid way to look at it, too.
- hsavit1 8y agoIf Apple is indeed granted the patent on Swift's optional chaining (as was recently posted https://forums.swift.org/t/apple-is-indeed-patenting-swift-features/19779 https://forums.swift.org/t/apple-is-indeed-patenting-swift-f... ), we wouldn't see this in future Javascript, would we?
- k__ 8y agoIs it even a useful feature? Will it lead to many JS bugs simply disappearing and applications getting more stable or will it just obfuscate bugs in the long run?
- realharo 8y agoPresumably people will only use it in situations where null (or undefined, or however it works) is a valid and expected value for a particular property. In TypeScript, these properties would explicitly have a `MyType|null` or `MyType|undefined` type.
- deleted 8y ago[deleted]
- spiritcat 8y agoRoughly speaking, one less place where we need to use lodash. "or will it just obfuscate bugs in the long run?" Probably. :shrug emojii: But more stable in the sense of turning hard crashes into UI quirks.
- evv 8y agoI'm no lawyer, but I think the Apache2 license on Swift would mean that the JS community has access to the patent. https://github.com/apple/swift/blob/master/LICENSE.txt https://github.com/apple/swift/blob/master/LICENSE.txt TC39 (who defines Javascript) is a collaboration of several companies, so I'm not sure who Apple could/would even sue if this was proposed and adopted for JS. I doubt we would see legal activity over it.
- mrmr1993 8y agoI would have thought that Coffeescript's optional chaining, present at least as early as v1.0 in 2010[0], would have counted as prior art. [0]: https://github.com/jashkenas/coffeescript/blob/1.0.0/lib/parser.js https://github.com/jashkenas/coffeescript/blob/1.0.0/lib/par...
- nudpiedo 8y agowhy no one proposes as feature a header to make javascript strict with the newest standard and deprecate and drop compatibility from previous versions in the newer ones? Or even just complete support for asmjs with interop and program in completely other languages, especially since the person who wrote this seems to want to program in languages with different semantics...
- amitport 8y agoThe title is "Future JavaScript: what is still missing?"- he's talking about new language features. I wouldn't expect him to discuss "dropping compatibility" and "completely other languages"
- nudpiedo 8y agoMy point is, why continue bloating javascript if its main weakness are some of its historical design issues (preserved only for backwards compatibility.)
- burlesona 8y agoYes, this is a big issue for JS. So much effort is spent trying to make JavaScript be some other language instead, by developers who are stuck building stuff in JavaScript because they want to run it in the browser. At this point programming in other languages makes more sense and is arguably a better vision for “the future of JavaScript.”
- nudpiedo 8y agoActually it is a pity that so many languages compile to JS but have an FFI which is not really friendly towards the programmer or that requires some code to write adaptors etc. Let's see how it evolves with asmjs.
- Vinnl 8y agoWhat is the goal you want to achieve with this? If just programmer discipline, then that's what many people use linters for.
- louthy 8y agoType safety
- tobyhinloopen 8y agoTypescript!
- louthy 8y agoTypescript is missing from JavaScript?
- jenscow 8y agoA viable replacement.
- openloop 8y ago@-;—-
- sctb 8y agoThere will probably always be a snarky, jejune dismissal in every JavaScript thread, but commenters should think to themselves, “It doesn't have to be me.”
- yakshaving_jgt 8y agoI had that thought, but I don’t think it’s that unreasonable to hold JavaScript as a lost cause. Enough large projects are just using JavaScript as a sort of bytecode for the web anyway. I also find personally that recognising something as bad is the first step to making something better.
- sctb 8y agoThat's fine, but we're here to gratify our intellectual curiosity. There's nothing wrong with recognizing as such, it just needs to be done thoughtfully and informatively so we can have a discussion about it.
- Dylan16807 8y agoRecognizing something doesn't imply bringing it up constantly.
- jenscow 8y agoYes, I was being snarky - however, it is a valid concern. There needs to be a choice. (I write javascript almost every day)
- talltimtom 8y agoAn interesting thought for the future is if wasm will make other languages viable on the web. It would be interesting to see if anything else picks up steam as a serious competitor to JavaScript.
- marcosdumay 8y agoIs it just me or are those really making Javascript weirder? const func = do { let result; () => { if (result === undefined) { result = someComputation(); } return result; }; }; Shouldn't that be "if (result === undefined) then someComputation else result"? Why import functional style and proceed to make it inherently imperative with a return in the middle of the block? obj?.foo?.bar?.baz The point of optional chaining is that you can place functions within the chain. That seems to be a very surprising and useless way to do them.
- jenscow 8y agoIt's lazy loading - someComputation() is only called if func() is called, and called only once. Perhaps you might prefer: result || (result = someComputation())
- seniorsassycat 8y agoThis is the equivalent without a do expression. const func = (() => { let result; // cache return () => { if (result === undefined) { result = someComputation(); } return result; } })(); You could write it without the immediately invoked arrow funciton or a do expression if `result` is in the same scope as `func` let result; const func = () => { if (result === undefined) { result = someComputation(); } return result; } Result is in the same scope as func, inviting anyone to read from or write to it. In all three examples `func` is assigned a zero argument function. That function returns the result of calling `someComputation`, but it stores the value in `result`. If `result` is not undefined `func` returns `result`. `func` is a cached, memoized, or lazy-loaded version of someComputation. A do expression will return the last evaluated expression in it's scope, in this example that expression is `() => {...}`, not `return` because the inner anonymous function wasn't called. --- I think a clearer demonstration of do expressions is an assigning switch or ifelse const value = do { switch (someString) { case 'Monday': 0; break; case 'Tuesday': 1; break; ... } } const other = do { if (isPrime(n)) { 'prime' } else if (isOdd(n)) { 'odd' } else { 'even' } }
- reconbot 8y agoI love these proposals and while it probably makes sense for me to learn more about the languages that already implement it there's no denying that having them in JS is a win. =) I wish I knew about python's [itertools](https://docs.python.org/3/library/itertools.html https://docs.python.org/3/library/itertools.html) before I started making [streaming-iterables](https://www.npmjs.com/package/streaming-iterables#api https://www.npmjs.com/package/streaming-iterables#api) for example.
- AnyTimeTraveler 8y agoA sane and coherent dependency structure?
- _yawn 8y agoWhat we really need isn't more syntax, it's core features like threads, operator overloading, a large std library, some real form of serialization (JSON doesn't come close to counting), etc.
- deleted 8y ago[deleted]
- Legogris 8y agoHow is operation overloading a core feature and not more syntax? I like the infix proposal better. Operation overloading has a larger degree of obfuscation.
- larzang 8y agoOr even more basic things like "a date/time implementation that isn't a horror show" or "\w that behaves like \w in every single other regex implementation out there when the unicode flag is on".
- genezeta 8y agoI was tempted to cite Antoine de Saint-Exupéry's quote on perfection, but we all know that, right? But then again, even the author mentions at the beginning the "risk of adding too much" and, well, I wonder if this has not already happened to JavaScript.
- RHSeeger 8y agoTo be fair, since JS needs to be so backwards compatible, it's difficult to take things away.
- wereHamster 8y agoJS is a language where new features can only be added by changing the language itself. There are other languages where new features can be implemented as third-party libraries. This allows people to experiment with new approaches to problems, try out new features and test them in real world. Once the community agrees on their usefulness, they are integrated into the standard library so everyone can profit. These are languages where you can't really remove that much, from the language itself. And any new language features (changes to the core language itself) are driven by "what is the minimum change we need to do to allow third-party code to grow even better" rather than … well, whatever that thing is that the JavaScript community is doing.
- benbristow 8y agoI'd like to see guard clauses. Don't know how they'd be implemented though.
- seniorsassycat 8y ago1.1 Comparing objects by value I _think_ I'd prefer a standard `equals` method, or more likely a `[Symbol.equals]` method. With `[Symbol.equals]` and `[Symbol.hash]` we could also build collections for objects.
- danShumway 8y agoI feel like there's something I'm missing with do expressions. Are they purely syntactic sugar? What can I do with a do expression that I can't do with an immediately invoked anonymous function? The examples the article gives don't really look all that syntactically different to me. const func = (() => { let result; // cache return () => { if (result === undefined) { result = someComputation(); } return result; } })(); const func = do { let result; () => { if (result === undefined) { result = someComputation(); } return result; }; }; And I guess I wouldn't be able to recurse in a do expression like I can with a named function? So it's not like I can actually universally stop using immediately invoked expressions everywhere.
- burlesona 8y agoYou’re not missing anything, as shown in the article it’s just sugar.
- snek 8y agoThey also inherit break/continue/yield/await/return/etc, which an iife will cut off.
- tristanstcyr 8y agoSyntactic sugar I not a bad thing. In any sufficiently complex language, most features can be simulated with other primitives. If we didn't want that, we'd all be writing lisp. In this specific case, the IIF is harder to read. You have to go all the way to the end of the expression in order to realize intent. With 'do', you see it right away. Like anything in engineering, it's a question of trade-offs. Do the benefits of better readability outweigh the downside of making the language more complex?
- burlesona 8y agoThere are some nice ideas here, but how many different ways do you need to do something? Since JavaScript has an especially high burden for backward compatibility you can’t really remove old cruft, and adding yet another way to (whatever) just makes the language harder to learn and harder to read. Warts and all, one of the best things about ES5 and earlier is that the language was so simple that you could pick it up in a day. The later additions have added developer convenience for sure, but at the expense of taking something simple, consistent, and very easy to read, and turning it into a complex and subtle language with a lot of redundant syntax. For example all the different syntaxes for defining a function with the subtle differences between them. And in this articles proposal - since switch doesn’t do what I want, we’ll have both switch AND case with different semantics and syntax. Ugh. At this point I’d rather see an effort to deprecate cruft or standardize features over throwing in new things.
- scarface74 8y agoThere was nothing easy to read about the callback hell that resulted in the asynchronous nature of JavaScript. Promises made it better but that was still verbose. Then async/await was added that made code read more linearly. There was also the unintuitiveness of how var declarations were always function scoped compared to how most developers would think that variables should be blocked scoped using let and const. Also I understand how prototypical inheritance works and I know that the class syntax is just syntactic sugar, but it is a lot more readable.
- ChrisSD 8y agoImproving some of the syntax was sorely needed but I think adding classes was unhelpful. I already have a hard enough time teaching programmers about prototypical inheritance without the language actively lying to them. And it feels like an odd move in that class based OOP isn't the zeitgeist it once was. Shoehorning it in feels like a throw back to 90's and 00's.
- scarface74 8y agoThe two most popular statically typed OOP languages for servers are still C# and Java. Besides JavaScript, the most popular scripting language is Python (let’s ignore PHP for now) which is class based. In the mobile space, Swift, Java, and now Kotlin are all class based. “The zeitgeist” is different than “what companies are paying real money for”. Besides, even with OOP based inheritance, the language is still “lying” just as much. Most developers who don’t understand how the lowest level of computers work don’t understand that when you call a function it’s always basically passing in a this pointer to one static instance of the function.
- danShumway 8y agoThere's some interesting stuff in here, but I'm noticing a large chunk of it is syntactic sugar. Keeping the extensible web manifesto in mind, I wonder if maybe what we really want is to have some kind of standardization around transpiling code. With new features like promises, we had extensive testing via user libraries before they made their way into the language. But with these kinds of syntactic features, that doesn't seem to be happening. If a feature is almost purely syntactic sugar, maybe it would make more sense for it to be supplied via a transpiler rather than being baked into the core language? Are there pain points or disadvantages to libraries like Babel that we could address via the core language instead?
- scarface74 8y agoYes it makes the toolchain more complicated and it makes debugging slightly harder. On top of that having it as a standard means you can go anywhere and just use it without worrying about which transpiler they are using.
- danShumway 8y ago> Yes it makes the toolchain more complicated and it makes debugging slightly harder. Are there ways we can help with this? Improvements we could be making to sourcemaps? Maybe we should be looking into adding new descriptors that are designed specifically to help generated code get read by debuggers? Maybe some kind of support for marking regions of code so you can run multiple transpilers on the same codebase? I dislike transpilation in its current form, but I can think of things off the top of my head that would make it easier. > On top of that having as a standard means you can go anywhere and just use it without worrying about which transpiler they are using. Fair enough, there are definitely advantages to having a large set of core features. But if you look at languages like modern C++, it seems that there are also disadvantages that come along with that. Given that the web is far more permanent than most other languages (we can never remove a JS feature), are the advantages of having one code style worth the disadvantages of not being able to test new syntax in the wild before we standardize? There's a balance here -- I like lodash, a lot. But I don't want lodash to be part of the core language. Maybe some syntax fits into that category as well?
- openloop 8y agoA language. Come on...the title is clickbait I had to. And no I didn’t read an article about modern javascript.
- tobyhinloopen 8y agoI may have overlooked it, but I want actual proper integers. Not doubles, just integers. I also missed the awesome bind-operator. EG: const getFoo = () => this.foo; const bar = { foo: 1 }; console.log(bar::getFoo()); // 1 https://github.com/tc39/proposal-bind-operator https://github.com/tc39/proposal-bind-operator
- snek 8y agohttps://github.com/tc39/proposal-bigint https://github.com/tc39/proposal-bigint is shipping in v8 (chrome and node) and firefox is about to ship
- laacz 8y agoJust hung Chrome tab by running "2122n 12122n" in console. Had to use task manager to kill it.
- TheAceOfHearts 8y agoYou could use the same technique as asm.js for acquiring and handling integers. Unary `+` always produces a Number or an exception. Bitwise operators treat their operands as a sequence of 32 bits, so a bitwise OR with 0 will cast the value to a 32-bit integer: +value|0 There's also TypedArray [0]. I think you'll be interested in the BigInt proposal [1] [2], which is stage 3. It's already available in Chrome, and behind a flag in Firefox. Now that it's possible to accurately represent 64-bit values, we're getting BigInt64Array and BigUint64Array. [0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... [1] https://github.com/tc39/proposal-bigint https://github.com/tc39/proposal-bigint [2] http://2ality.com/2017/03/es-integer.html http://2ality.com/2017/03/es-integer.html
- chrisseaton 8y ago> I want actual proper integers. Not doubles, just integers. Why exactly do you want that? Is it arbitrary precision you want? Is the 56 bits or whatever not enough for your use-case? Or do you find the range checks are too expensive in practice?
- pfooti 8y agoI'd like to see a real, useful implementation of weak references, for use in value caches, or a way to manually take over garbage collection for some objects. Basically if I want to keep a cache of expensive objects that will grow monotonically, I need to do a lot of work to make sure I'm not leaking memory right now, but if I could instead store in a Map<string, weakref>, it'd be much easier, things could go out of ref and I could deal with that.
- ralusek 8y agoYou're aware of WeakMap and WeakSet, right? You can't key by strings, but I'm not sure you'd want to.
- pixelcort 8y agoYes, but a weakref by string or number would be quite useful for ORM caching.
- pfooti 8y agoYeah weakmap and weakset basically do the opposite of what I want. The keys are weakly held rather than the values, which does no good for an ORM cache. One cannot even iterate over the keyset in a weakmap (so you can't do a lousy o(n) lookup version of what I want.
- PretzelFisch 8y agoI would like a null conditional operator and null coalescing operator. return data?.error?.message ?? "no error"; Also pattern matching would be a big win.
- Forge36 8y agoNull coalescing is already possible with ||. Though I'd like ?? If it worked for undefined coalescing as well.
- untog 8y agoYou still have to be more verbose, though. You can't do obj1?.obj2 with ||, not could you do obj1?.method()
- coldtea 8y agoHow does || differentiate null from e.g. 0 or ""?
- GordonS 8y agoIt doesn't - it tests for a "truthy" value.
- charrondev 8y agoThese are not the same. let val = 0 val || 30 // 30 val ?? 30 // 0 The same goes for other falsy values.
- untog 8y agoAbsolutely this. I've done work in both Swift and JS (well, Typescript) and every feature on my wishlist is from Swift. Null operator like you suggest, guard statements and structs, which are the best equivalent to value-type objects as outlined in the article.
- kangax 8y agoYep. Both are stage-1 proposals: https://github.com/tc39/proposal-optional-chaining https://github.com/tc39/proposal-optional-chaining https://github.com/tc39/proposal-nullish-coalescing https://github.com/tc39/proposal-nullish-coalescing Recently started using optional chaining in our codebase (via Babel 7) and it's great so far. Also gives us proper static typing safety unlike Lodash `get(...)`
- stephenr 8y agoReally? Still no way to specify argument types?
- c-smile 8y agoJust argument types are useless. Either all variables shall have types and so static, compile time analysis can be performed. Or no types at all.
- stephenr 8y agoUseless to you maybe.
- c-smile 8y agoTo anyone. Types are useful only if they can be checked/verified at compile time. Types in only arguments cannot be verified by compiler. So type mismatch can be checked only at runtime. So would be this: function foo(a:Number) { … } Is essentially this: function foo(a) { if( !(a instanceof Number)) throw "Not a number"; … } And that rises the question: who and at what moment will handle such errors?
- stephenr 8y agoThey’re plenty useful if you want to write a library and distribute it (either publicly or within an org) that tells users of the library what they did wrong (other developers) without having to insert type checking boilerplate into every single method.
- int_19h 8y agoTypes are a subset of contracts. Contracts are plenty useful at runtime, as evidenced by the fact that every language that offers design-by-contract (most of which are statically typed) still provides runtime checking facilities. Furthermore, they're usually enabled by default for preconditions, which is what argument types are. Nobody will handle such errors - contract violations are not supposed to be handled, they're a coding bug. You "handle" them by fixing the caller such that it never violates the contract. The benefit of having a runtime check is that it can detect the error instead of silent wrong behavior potentially followed by state corruption and further bugs. Most of the time, these will fire in automated tests, anyway.
- sebringj 8y agoTypes :) I tend to use underscore for just _.get or _.set these days as I have most everything else I want so having some built in way to do that would be nice but the elephant in the room here is the toolchains being built quietly behind the scenes that support web assembly from strongly typed languages with much better load times and performance. The WALT one and the oCaml React one is pretty cool but would be nice if there was an official strong-typed JavaScript version for this scenario being built as a spec.
- scarface74 8y agoI know it will never happen, but something like LINQ in C#. Not just functions that iterate over collections, but the whole idea of language integrated queries where code is turned into expression trees that can be parsed and translated by providers. For instance in C# you can take the same LINQ expressions and they can be translated to sql by EF or MongoQuery by the Mongo driver at runtime.
- kristiandupont 8y agoWithout type safety, there doesn't seem to be much to gain from this besides for a bit of syntax checking?
- scarface74 8y agoIn this case of LINQ, I can call methods like: var retiredMales = custRepo.Find(c => c.Age > 65 and c.Sex == “M”) and then have an interface with a member: List<Customer> Find(Expression<Func<Customer,bool>> expression): You can implement three classes for that interface - one that uses EF, one that uses Mongo, and one that just uses in an memory List for unit testing and they all translate the expression to the underlying data store. Theoretically, you could have an “expression” type in JS that can be parsed by the provider.
- jauco 8y agoWhat you’re looking for is the backtick in lisp. Or more generally: lisp macro’s where a function can inspect the ast of an argument and base it’s result on that. For those who gave never used linq: this allows the above function to translate the function to a sql, sparql or mongo query depending on the currently selected backend
- amelius 8y agoSimplicity and elegance
- Paperweight 8y agoI feel like you could take a subset of JavaScript and make a new "JSLite" language that forces you to do things in one, proper best way. It would be a great way for new developers to learn modern techniques.
- tapirl 8y agoReading is more frequently than writing in reality.
- tapirl 8y agoYes, it looks modern JS and C++ are on the same road now.
- enobrev 8y agoA lot of great and well-thought-out suggestions here. Whenever taking deeper dives into Javascript, I tend to find myself on 2ality.com though google searches and whatnot. They do well when it comes to breaking down the language and features. I'm a fan of 2.2: destructuring switch, although I occasionally employ something similar in JavaScript and other languages with a `switch` statement: const resource = await fetch(jsonService); switch (true) { case resource.status === 200: console.log(`size is ${resource.headers['Content-Length']}`); break; case resource.status === 404: console.log('JSON not found'); break; case resource.status >= 400: throw new RequestError(res); break; } It's missing the destructuring aspect, so the first case is a bit more verbose, and I imagine there's better potential to optimize something like the OP's example. But it has a similar effect to the example and works today. Slightly related: I really wish `case` worked with brackets instead of break, similar to OP's example. It looks cleaner and is easier to visually parse. I suppose that's only better if you prefer brackets (which I do).
- amelius 8y agoA reference implementation in a purely functional language.
- snek 8y agoHow about a reference implementation in itself :P https://github.com/devsnek/engine262 https://github.com/devsnek/engine262
- JustSomeNobody 8y agoNeeds more punctuation. I don’t know about the rest of y’all but I get disappointed when I look at JavaScript and it’s not awash in a sea of angle brackets. But seriously, be careful not to ruin it with too much “I need this!”
- igotsideas 8y agoAfter messing with Elixir for a while, i really enjoyed the piping feature. I’m sure it will be added to js and I’m genuinely excited cause it makes reading code easier for me, given that your function names tell you what the function does
- superasn 8y agoI wish JavaScript would let me declare scoped variables inside if statements like this: if (let myVar = exp) {
- dan-robertson 8y agoShould this also behave like if-let in rust so if the pattern doesn’t match then it acts as false? E.g if(let [x,y] = thing) ... Would only be true when thing is an array with two elements (not super sure bow pattern matching is defined in ha. I would guess that actually if the match fails then things get to be undefined which means the match can’t really fail so this would likely be confusing)
- c-smile 8y agoHere are things that I've added in Sciter's script (https://sciter.com https://sciter.com): 'like' operator that is used as a match if( obj like /[A-Z]/g ) … // "string".match if( obj like {name:String} ) … // obj has name string field if( obj like [String,Object] ) … // obj is an array of at least two elements, string and object. extended switch() : switch(obj) { case 1: … // standard JS like /[A-Z]/g: … // RegExp, Object, Array match instanceof cls: … // obj instanceof cls in [1,2,3]: … // obj }
- c-smile 8y agoObject literals to allow `-` in identifiers, so these are valid constructs: var style = { font-size: 10px, border-width: 1em } New built-in value types: Length, Duration, Angle, Color. So these are valid constructs: this.timer(200ms, function() {...}); element.style.width = 1em; var c = rgb(128,128,0); assert c.r == 128; var (h,s,v) = c.toHSV(); Float and Integer are distinct types as these are different entities indeed.
- c-smile 8y ago'in' operator follows `contain` idiom for collections. 1 in [1,2,3] -> true "foo" in {foo:1,bar:2} -> true Real namespaces: namespace Foo { function a() { return "a"; } function b() { return a(); } // Foo.a() call } namespace Key { // enums const ENTER = 13; const SPACE = 32; } if( evt.keyCode == Key.ENTER ) ...
- c-smile 8y agoby value and by reference comparison: [1,2,3] == [1,2,3] -> true in Sciter, false in JS [1,2,3] === [1,2,3] -> false in Sciter and in JS {a:1} == {a:1} -> true in Sciter, false in JS {a:1} === {a:1} -> false in Sciter and in JS
- _bxg1 8y agoMuch of this reads like the author wants JavaScript to be something it isn't. The requests for compare-by-value data structures, immutability, and true concurrency are huge paradigm shifts from the heart of the language whose implementation would no doubt come with significant complexity overhead.
- GordonS 8y agoI'd like a decent standard library. These days I work mainly with C#, and to a lesser extent Typescript and JavaScript - the anemic nature of the ECMAScript standard library is really jarring.
- dehrmann 8y agoI mostly work with Java and Python. Whenever I use Javascript, the lack of basic data structures other that arrays and objects is always jarring.
- city41 8y agoThere is also Map and Set.
- ilikehurdles 8y agoComing from clojure, I find that it’s not data structures that JS lacks, just functions/methods to manipulate them and a consistent approach to their mutability and return values.
- hajile 8y agoObjects, Arrays/lists (technically objects), TypedArrays, Set, Map (with weak variants). What other important structures did you have in mind?
- dehrmann 8y agoArrayDeque, LinkedHashMap, TreeMap, PriorityQueue, even LinkedList. Their interfaces have gotten pretty built-out, too, with methods like computeIfAbsent. It also has a rich collection of concurrent data structures, but those aren't useful in Javascript (yet).
- hajile 8y agoLucky for you, JS already has good solutions for most of those things. LinkedList is almost indistinguishable from an growable array. Since the JS array grows by default, you're covered for the kinds of things you'd want a linked list for (in fact, most older JS implementations actually implemented arrays as linked lists). ArrayDeque's big claim to fame is add/remove from both ends. That's also covered by the standard array (shift/unshift, pop/push). Linked hashmap's big feature is maintaining insertion order. The JS Map type does this automatically. JS Objects don't do this officially, but since so much legacy code depends on this "feature", it is implemented for objects across all major browsers. Priority Queue isn't in JS, but I'd argue it's rather niche and rather few async frontend JS projects need it. On the backend, one extra import is hardly a big deal. There is also no treemap. They are simple to implement (esp with proxies). JS objects store all keys as strings and `Object.keys(foo).sort()` is probably about as fast. As an additional issue, JS maps can have keys of different types, so deciding how to perform that sort would be very difficult. This also seems like a niche issue that belongs outside the standard library.
- pragueexpat 8y agoDeep clone objects
- _blrj 8y agoRestraint.
- Waterluvian 8y agoA built-in way to conveniently iterate n times. Anyone have a sensible pure JavaScript example for: range(5).forEach(fn) I haven't found one that felt small enough to use inline. It end up using traditional for loops.
- blinger 8y agoArray.from({ length: 5 }).forEach(fn)
- Waterluvian 8y agoOh not bad. I wasn't aware of that! I'm guessing it constructs the whole array upfront. Maybe there's a generator way to do it too.
- jimrandomh 8y agoUsing underscorejs or lodash: _.range(5).forEach(i => {/*...*/})
- klardotsh 8y agoI really don't love it, but Array(5).fill().forEach(() => console.log('hello'))
- ljm 8y agoI've also taken to: Array.from({ length: 5 }).forEach(...) But I'm not sure what you gain from that compared to just wrapping a for loop in a function. You still don't get ranges the way you do in, say Ruby: ('a'..'z').each {|letter| puts letter }
- klardotsh 8y agoYeah, I mostly work in Python, where ranging and slicing is amazing. JS has a lot to catch up on in that regard.
- c-smile 8y ago
- topynate 8y agoDependent types. You think I'm joking, but check back in ten years...
- pmontra 8y agoIn this code please remove the when keyword if possible. It's only noise. The Elixir equivalent works well without it. Other than that I'd love that kind of pattern matching on JavaScript. case (resource) { when {status: 200, headers: {'Content-Length': s}} -> { console.log(`size is ${s}`); } when {status: 404} -> { console.log('JSON not found'); }
- moogly 8y agoThey're going to have to iterate on that proposal IMO, until they've reached something closer to Rust. C# 8 went with this[1], and that should be proof in the pudding that you can make something more ergonomical/palatable in a C-based language. [1]: https://blogs.msdn.microsoft.com/dotnet/2019/01/24/do-more-with-patterns-in-c-8-0/ https://blogs.msdn.microsoft.com/dotnet/2019/01/24/do-more-w...
- Findeton 8y agoI'm implementing delta JSON mutations. I think with time people will embrace the idea.
- alan_n 8y agoI was scrolling through this and I was like, where is optional chaining? Then when he gets to it, he's a bit against it because it's easy to write bad code. What? People still do nested checks like this all the time! It's not changing anything beyond making them more readable and I think more obvious when you think something might not exist (e.g. `some.very?.nested?.property` vs `some.very.nested?.property`). Sometimes it's not so much the nesting that makes it unreadable either, but that you're checking multiple objects, imagine writing `some.nested?.property && other.nested?.property`. It's like saying promises shouldn't have been added because you can still write bad code with them and create nested promise hells ( I sure did when I first learned them). Isn't it better to say, no, best practice is to add ? only where you actually need them. The solutions he cites are not really solutions, they're just abstracting the problem away which most of as already do, but then the abstraction becomes hard to read because those checks have to be somewhere. Worse I think is the comparing objects by value idea. I think it would be way too easy for beginners to reach for that solution. There are often better work arounds, it's quite rare imo to need to do a deep nested check of two objects that could be very different (i.e. contain different properties). Plus it's not like using a helper function is that verbose and a custom one can be really fast (if both objects contain the same properties, creating a function that "manually" checks for them all is blazing fast), same thing with deep clones. Things I would really like, from most to least: optional chaining obviously, realms, pipeline operator, optional type checking, and enums (you can sort of fake them though, hence why they're last)
- regularfry 8y agoThe difference between Promise and optional chaining is that you can (and should) redesign your code not to need deeply nested data access. The pain of doing deep null checks everywhere is a code smell in itself, and optional chaining just covers it up. Making a bad thing easier to do is bad. You can't redesign your code not to need asynchronous callbacks. They're fundamental, given the constraints of the language implementation. Given that, it makes sense to make them as painless as possible (and I'd argue async/await is... well, it's not good, but it's better than Promise alone).
- alan_n 8y ago
- renke1 8y agoSave navigation and equals/hashCode (as protocol, not using that ValueType thingy) are fine and definitely useful, but otherwise we should avoid adding even more syntax elements to JS.
- mschuetz 8y agoThe single most important feature I'd like to see in JS are types. Typescript seems nice but I don't want to need a transpiler, especially since I'm doing a lot of live-coding in JS and compilation/transpilation times >50ms are already too much. Other than that, JS could benefit tremendously from a more complete standard library, and a build system, including a file watcher, that doesn't rely on 200 nonsensical dependencies.
- james-mcelwain 8y agoI'm confused -- any static typing system is going to need a compilation step to check types. How is typescript any different than "javascript with types" would be? If your goal is live coding, a dynamically typed language will always be faster.
- mschuetz 8y agoTypescript right now requires basically two compilation steps, and it doesn't have decades of compilation optimizations behind it that JS has. If types or typescript itself, were directly supported, things would be so much faster.
- jcoffland 8y agoReminds me of this quote: “Perfection is achieved when there is nothing left to take away.” --Antoine de Saint-Exupéry This principal should be applied more to programming languages.
- tomerbd 8y agostatic typing
- alexandercrohde 8y agoWhat's really missing from javascript? 1. The ability to run my code without transpiling and reinstall dependencies for 10 minutes. 2. The ability to know which of the last 5 version of javascript to use. 3. Stability in my dependencies. 4. Consolidation and standardizing on established frameworks. Basically undoing all the mess the ecosystem has done over the last 8 years.
- JeremyBanks 8y ago1. Stop supporting IE11. 2. Whatever has 99% support in browsers your users actually use. 3. Yes. 4. It’s called React.
- alexandercrohde 8y ago4. I don't actively javascript anymore (for the reasons listed above), but isn't there still a bunch of variation within that (e.g. something called "Vue" and something called "redux")? Does google use this "react" ? In most traditional languages if you learn a framework you'll get a decade of use out if it. ROR was the first hacker community to really screw this up.
- JeremyBanks 8y agoRedux is a nearly-ubiquitous complement to React, not an alternative. Redux handles the data, React handles the interface. Vue got a lot of attention on Hacker News because it was new, but it has plateaued with at most 1/8th of React's market share. It is not going to be replacing it. React is more dominant than any JavaScript technology has ever been except maybe jQuery (whose responsibility was a lot narrower). It's not my personal favourite, but I appreciate having a de-facto standard across almost everything I have to work on. Google is mostly irrelevant to this discussion: they have extreme Not Invented Here syndrome and cling to terrible in-house technologies for front-end development. (They have been gradually increasing their React adoption over the last few years, but it will probably remain small.) They were once the world leader in JavaScript development, but they haven't treated it seriously and are now significantly worse than all of their competitors. If you go to Google, you're committing to learning a lot of non-transferable knowledge (in addition to a lot of valuable practices).
- h1d 8y agoI wish more languages follow the sense of being fun to code like ruby. [1, 2, 3] - [1, 3] #Yields [2] The code is readable, intuitive and short yet many languages never have this simplicity. JS example. https://stackoverflow.com/questions/1187518/how-to-get-the-difference-between-two-arrays-in-javascript https://stackoverflow.com/questions/1187518/how-to-get-the-d...
- rgovostes 8y agoThat doesn't seem super intuitive to me. I assume that [1, 2, 3] + [1] == [1, 2, 3, 1] but then if I subtract [1] again, does it take away the first 1, or the last 1? It turns out it removes both of them. So subtracting a list is not the inverse of adding a list. In Python, there is the distinction between lists and sets, and while both support the + operator, only sets support the - operator for this reason.
- ricardobeat 8y agoFirst one is called 'concatenation', second 'array difference'. It does require a one-time look at documentation, which doesn't take anything away from the fun or practical aspects. There is no expectation that they are inverse or commutative.
- chx 8y ago> There is no expectation that they are inverse or commutative Please. I am not a Ruby coder but I fully expect any language that a + b - b is just a and also a + b - a is just b.
- lifthrasiir 8y agoUh, floating point numbers don't.
- ricardobeat 8y agoThese are not mathematical operators (hence the “overloading”).
- TravelTechGuy 8y agoNot sure if it had been mentioned already, but I think we could benefit from cancellable Promises. Many of the modules and libraries currently support Promises, and `async/await`, but try to find a way to cancel a long-running Promise. Some libraries have resorted to using their own mechanisms, and some (e.g. `axios`) resorted to using a withdrawn TC39 proposal. I'd like a standard, easy way to cancel a Promise. I know it's not simple, and Promises can wrap around other Promises, etc. but if I'm e.g. uploading a large file to a server, there should be an easy way to provide my users with a "cancel" button that works.
- tjallingt 8y agotheres the AbortController [1] that can be used on a few new promise based APIs such as the Fetch API [2] [1] https://developer.mozilla.org/en-US/docs/Web/API/AbortController https://developer.mozilla.org/en-US/docs/Web/API/AbortContro... [2] https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
- TravelTechGuy 8y agoBut there's no easy way to inject this AbortControl into existing libraries, or use it easily with async/await. I'm looking for an easier standard.
- devwastaken 8y agoRenderer access. It should be possible for js to control and get callbacks for rendering and event updates in styling. Though that's a browser feature, not really js
- AgentME 8y agoYou might be interested in the CSS Paint and Layout Worklet proposals.
- z3t4 8y agoPlease stop adding new syntax, it only makes the language uglier. Instead of a special syntax for comparing objects, just add a function to Object.prototype.
- zzo38computer 8y agoI disagree. Stuff should not be added to Object.prototype, although it can be a function in Object itself (such as Object.equals or something, not Object.prototype.equals). You are correct it does not need a new syntax though.
- adrianhel 8y agoI would like optional typing for the few places where it would be very useful. But people would enforce all types way too much, so I'm kind of on the fence.
- vertline3 8y agoI like JS, I like the new features since es5, although I liked es5 also, I notice that the updates are now yearly it seems, which is mostly good since there was maybe a long delay in the past, but can be bad if there become too many features.
- amiga-workbench 8y agoDevelopers with pragmatism and taste.
- jorblumesea 8y agoI know this is a really contentious idea but I'd like javascript and typescript to merge into the same language. Type safety is the huge 800lb gorrilla in the room.
- moogly 8y agoI know at least I will never ever go back to JavaScript after having used TypeScript for a bunch of years.
- deleted 8y ago[deleted]
- deleted 8y ago[deleted]
- a_lieb 8y agoAs someone who teaches JS on the side, I'm literally scared of the idea of introducing another construct called "case." Especially one that goes in the opposite place of where the "case" normally does: "switch ... case" vs. "case ... when." JavaScript is already jam packed with subtleties and gotchas that make it hard to learn, including situations where two things have the same name or the name doesn't quite match the underlying concept: C-style "for" vs. "for ... in" vs. "for ... of," object vs. Object, Object.prototype vs. "the prototype of the object," etc. We don't need another one of those. I'd actually like this if it used another word than "case." "choose ... when", maybe? Kinda awkward, but I bet someone could think of something better. "case" has the nice feature that it's already a reserved word, but it's not valid syntax to have a variable name right next to an open brace, so the parsers could figure it out.
- paulie_a 8y agoNot having to install the shit show of conflicting dependencies. Get a formal package manager instead of the twenty different ones. Basically take a look at python and realize the js ecosystem could actually have nice things.
- defnotarobot 8y agoAs someome who has spent the last year primarily with Elixir, it is impossible to overstate how nice pipeline |> is. It is one of the most convenient and readable pieces of syntax, and one of the primary reasons I pause before using javascript instead of Elixir in a given moment.
- zzo38computer 8y agoSome things I wanted in JavaScript is a goto command, and macros. They mention objects to compare by value, and I had a bit different idea which is a UserPrimitive function which has a similar meaning (but different; user primitives would also allow some degree (but still restricted in some ways) of operator overloading). Bigint is a good thing they added. Sometimes you need to deal with 64-bit integers, and other times you might want unlimited range, so that helps. However, some operations that are not currently built-in perhaps should be in order to be more efficient, such as log2 of bigint numbers or counting trailing bits. A built-in RegExp.quote() function is another thing (although it is easy to make, it seem to me it is something that ought to be built-in). If macros are implemented, then many features can be done by macros and do not need to be built-in features. One feature of JavaScript that I dislike is automatic semicolons. And yet, many proposals (including these) may be rejected if better ways are found.
- blitmap 8y agoThe only thing I absolutely hate is the import-as bullshit inspired by Python. I was told this was to assist static analyzers, but when you compare it to destructuring syntax you just get annoyed by the duplication. +1 for pipeline operator +1 for a destructuring switch
- madmaniak 8y agoES5 > ES6+
- 8bitsrule 8y agoPython writes to local files using native function open. Javascript has no native function. Because...? We can open a window, write arbitrary text to it, use the browswer to 'Save as...'. Close but no cigar. I'd like to use JS for a lot more than the web. MS Basic wrote user-entered text to a file 40 years ago.
- thomasfoster96 8y agoI’m not sure about you, but I consider JavaScript running in my browser not being able to write arbitrary text to files to be a good thing. Otherwise, Node.js can do exactly what you just said Python and MS Basic can do.
- 8bitsrule 8y agoWhoa hoss. Bit of overkill there. I can already write to file with 'window.(something).createObjectURL' ... which queries user. I simply suggest that 'future javascript' open() (or whatever) supports that with no-more-code needed.
- pcmaffey 8y ago> Comparing objects by value A handy helper I use all the time for this: export const jsonEqual = (a, b) => JSON.stringify(inspect(a)) === JSON.stringify(inspect(b))
- rpz 8y ago>1 2 3 + 3 4 5 4 6 8 Extend the operators to work on lists!
- nrb 8y agoThat would confuse the heck out of people who would expect + to concat the arrays (I guess not much better than the current behavior of string concat) Obligatory lodash reference: _.map(_.unzip(arrays), _.sum)
- Mugwort 8y agoJavascript is still missing simplicity, consistency and a unified core set of ideas. It will always be that way too. Javascript will always be something grudgingly accepted or used with some misgiving. ES6 has some very nice features and the good parts of javascript stand out as much as the unfortunate inconsistencies lurking inside the language. People know how to use it. Some use it quite well but I always get the feeling I have to step around carefully and not make a dumb mistake in js which is easier to do than almost any other language except say PHP. Web assembly should open up some badly needed possibilities. All we really need is a consistent API. A world without js? I hope so.
- jdpigeon 8y agoI feel like this opinion is too popular so I just want to respectfully speak my peace. I'm a relatively new developer and I never learned any of the languages that a lot of the old guard fawns over, but after learning coding with Racket, Java, and Python, JavaScript (especially TypeScript) has always felt, and continues to feel, awesome.
- Swalden123 8y agoI agree with @jdpigeon People who come from other languages often make “dumb mistakes” because they try to apply their existing mental models of programming to a language that works differently.
- leshow 8y agoI don't know what languages you're referring to but I didn't have my eyes opened until I spent significant amounts of time learning Haskell. I think any language with suitably advanced type system would do: ocaml/reason, rust, swift, etc. All the OO c-derived languages feel super bland to me since they all deliver equivalent expressive power, more or less. You get a really different experience once you get a language with a more capable type system. Honestly I'm kind of surprised that Racket didn't stand out to you, it's a super cool language and very different from everything else on your list. How much time have you spent using it?
- austincheney 8y agoJavaScript still is often extended via inheritance, such as classes and modules. This is unfortunate because inheritance is the opposite of simple, putting things together instead of taking them apart. One addition that could greatly improve simplicity is assignable blocks. A block provides scope, much like a function, but accepts no input and returns nothing. Most functions I write take no input and return undefined because I only need them for code reuse by reference. Imagine code like this: if (expression) myBlock else otherBlock;
- int_19h 8y agoWhat's the benefit over myBlock() and otherBlock()
- austincheney 8y agoYou can write code withou the curly braces, but is generally considered a bad practice. if (expression) myBlock() else otherBlock() is really if (expression) {myBlock();} else {otherBlock();} In that case a block is still there and not reused. Both the semantics and structure are different if the block itself were reused. You could extend the above like so: if (expression) {myBlock();x+=1;} else {otherBlock();} If instead the block were reused that would not work. A finer degree of separation is imposed by reference that reenforces separated structures by name. Separation is the foundation of simplicity. It also makes for code that is easier to read like a natural language sentence.
- int_19h 8y agoI'm still not following. Why would you want to reuse blocks (scopes?) rather than code?
- stevedekorte 8y agoCoroutines (unlike async/await) would allow one to wait on an async result without losing the stack which is waiting. This would avoid the need for (often) inscrutable callback state machines (Javascript's version of GOTOS).
- int_19h 8y agoAsync/await has a logical stack that is distinct from the physical stack(s). Quality tooling would show you said logical stack instead of a mish-mash of physical stacks from different async functions that happen to be intermingled on the current thread. Example: https://blogs.msdn.microsoft.com/devops/2013/07/01/debugging-asynchronous-code-in-visual-studio-2013-call-stack-enhancements/ https://blogs.msdn.microsoft.com/devops/2013/07/01/debugging... So you don't need to deal with "inscrutable callback state machines" anymore so than you need to deal with the assembly labels and jumps that your for-loop compiles into.
- luord 8y agoEntirely off-topic (or maybe not given the nature of like 20% of the comments here), but it's getting seriously annoying how in every thread even tangentially related to programming there are ten or so people (not the same people, not trying to call anyone out) trying to proselytize about functional programming and/or static typing. They're not panaceas, they're just alternative approaches to programming no worse nor better and they don't need to be brought up in every. Single. Post.
- nambit 8y agoHow can you say they're no worse nor better? That's a loaded statement without qualification. It is entirely possible (if not highly likely) that one approach is better (for all or most use cases)
- luord 8y ago> That's a loaded statement without qualification. That "without qualification" is an odd thing to say regarding a couple of (flamewars) discussions that have been going on for sixty years. There are thousands, millions of lines of literature discussing advantages and disadvantages of every paradigm and every type system. > It is entirely possible (if not highly likely) that one approach is better And when such approach is discovered and/or conclusively proven as better, I'm sure the entire industry will converge upon it. Computer science is, after all, a science. What I just wrote is obvious and common knowledge that I'm sure you're aware of, but I couldn't think of another way to explain my point. Hopefully I was clear.
- servercobra 8y agoI would love some of the syntactic sugar from Swift. Swift's `guard` and `if let`, along with the nil coalescing mentioned in another comment make Swift a joy to write.
- int_19h 8y agoFor value equality, I feel like the whole value/reference type distinction is an unnecessary distraction. What we really need is different operators to handle object identity comparisons and value comparisons. Whether an object can be meaningfully compared by value to another object is orthogonal to whether it's a value type or not - e.g. arrays are reference types, but there's no reason why any two arrays can't be compared element-by-element. One language that gets it mostly right is Python, where "==" always compares values, and "is" always compares references. Thus, you can use either for e.g. lists and sets, depending on what you actually need at any given time. However, Python fails in that it doesn't give the same flexibility in many contexts where the comparisons are implicit - e.g. in dicts and sets (it always uses ==, instead of letting the user specify an equality function). Ironically, a language that gets it fully right - including the standard library - is VB.NET. I'm not even sure that value types themselves are such a useful concept. A value type can be thought of as an immutable reference type, where any mutations done via the reference simply cause a new object to be created and the reference changed (semantically; under the hood, it can be easily optimized down to in-place update).
- IloveHN84 8y agoType safety, without using Typescript
- jillesvangurp 8y agoIMHO the list of changes presented here sort of half way gets you there to the (apparently) platonic ideal of being more swift or Kotlin like. It's better but seems a bit lacking in ambition because of backwards compatibility. I'd argue backwards compatibility is actually a lot less important in the JS world than it currently appears to be. Why not aggressively deprecate all the uglyness, broken semantics, etc. If you write ES 2020, or whatever they will call it, why would you still want broken floating point math, wacky equals behavior that nobody can explain with a straight face, etc. Just deprecate it, start disallowing it, and eventually remove it from the language in a couple of versions. Browser javascript is effectively a compilation target these days. Yes you can write in it directly but many people don't do that. Transpilers seem to be the norm these days. Mostly transpilers already do work around javascript legacy but they still have to deal with hiding some of the ugliness. The good news is that people update their browsers. So there is very little need for transpilers to be able to target old versions of browsers. Mostly they just need to deal with current and recent versions. With the emergence of WASM, that is becoming a more obvious compilation target. You can already run C, Kotlin, Rust, Code, etc. using it. Doing so, you bypass all of the legacy of javascript. It's just another compilation target for compilers. It's not such a big leap to simply run javascript interpreters/vms on top of WASM as well. Why not? It's not any different from doing the same with ruby or python. It would be a great way to support legacy applications and it completely removes the need for javascript to continue to support legacy features. IMHO, it would greatly simplify browser implementations if all they had to do is support running WASM + whatever standardized bindings they ship for things like the DOM, browser storage, webgl, etc. You could freeze a current version of v8, call it legacy js and use that to run legacy javascript if/when you actually need it and rely on a modern JS interpreter without any of the baggage. My guess is that running legacy js would very rapidly become a niche thing.
- jkbbwr 8y agoThe biggest thing that is missing in my experience is finalizers or context blocks. I need some way to free resources allocated inside emscripten. Either python style context managers or go style defer or c++ style destructors on scopes would be a god send.