I'm actually working through this book right now. I've been away from front-end coding for a bit and my weekend/evening project over the next month is to brush up on modern Javascript and ReactJS. This book is very well written and great re-introduction to JS/programming fundamentals.
For those interested--Besides this book, my current learning plan includes:
Javascript 30 by WesBos
Exploring ES6 [http://exploringjs.com/es6/]
Learning React-2nd Edition on O'Reilly Learning
The Beginners Guide to React on Egghead
Data Structures and Algorithms in JavaScript on Egghead.
I also used Kent C. Dodds' excellent "JavaScript to Know for React" article as an outline.
Whoa! You’re going to finish all seven (six?) of those books over the next month? Just on nights and weekends? How are you so productive? How do you not burn out, given that (I assume) you do software during the day? Honest question, from someone who is often down on themselves for being a slow coder, slow reader, and easily burned out.
Definitely don't get down on yourself--going through periods of low- and high-productivity is normal. I get burned out at work multiple times each year (I do mostly technical writing, training, and support). It just depends on how you look at things and how you measure success. I'm not a 10x developer, so I don't measure myself against 10x tech bloggers or other "experts". I just break my learning goals down into small, manageable tasks and revise as needed.
My measure of success is being able to understand development at a lower-level. Learning new languages, frameworks and building side projects helps me through the low periods and enables me to work more fluently with developers.
I have experience with Javascript and VueJS from a couple of years ago, so my goal is to catch up with modern JS (ES6+), brush up my JS core knowledge (not just frameworks) and learn ReactJS. It's very likely that I won't finish everything on my list this month, due to other obligations, but that's ok. I'm not competing with the experts out there, I just want to learn new skills and build things that I couldn't before. I also have a bit more time now that I'm stuck at home on evenings and weekends.
I'm beginning to think this kind of memory is hugely important for programming. It sounds counter-intuitive because devs work with text, but maintaining a visual representation of any project, current and future state, as well as the various machine states is a consistent way to be productive.
That's very helpful. But I'm talking about people with a special ability to remember everything after reading it once. My brother is someone like that and it's insane how much he remembers details of things that happened so many years ago.
Definitely the former--I'm just brushing up on my core JS skills and learning React for the first time. I currently use Vue for side projects, but I really like the React Hooks API.
The docs are great for a given tidbit, but for structure and "why" I personally don't always get that from the docs and I end up reading something from Kent that tells me why.
Kent's stuff is good but I have a niggle with him (and an annoyingly non-zero bunch of other bloggers): no publication dates on his posts. As someone who always makes notes of what I read, and who wants those notes to include publication dates, it annoys me that I have to look at the git source for a given blog post to find out when it was published. (Though at least with Kent I have that option...)
Web tech moves very fast. A good answer to a problem today will likely get superseded within a year. In such a context, dates become essential tools to help comprehend someone’s post.
So it is! I stand corrected - thanks! I am, however, still open to the possibility that I was right in the past, and that he recently added the dates. ;-)
Sure, you're right. They are quite good. But just from my perspective, I've been a backend engineer for most of my professional career and wanted to pick up front end dev. With little javascript/html/css knowledge, I used a couple different resources. I'm still learning, but I've found that just the official documentation doesn't quite get you there if you want to get the full picture.
I've been working through the following resources with a decent amount of success I think:
1. Fullstack React: The Complete Guide [0] - a wonderful book with a bunch of practical applications to build
2. Learn CSS Layout [1] - A nice write up for understanding what CSS actually is doing
3. Mozilla HTML Reference [2] - Can't get any better than this documentation
4. Eloquent Javascript 3rd Edition - Book being discussed, really enjoying working through it.
Obviously, the React and Redux documentation have been great as well. I don't think that just those really give you the full picture that you need though if you actually want to build professional web applications.
You’re absolutely correct and I don’t disagree. However I’d like to offer an alternative: unless you build a real world project you won’t ever feel comfortable with your learning. I used to be just like you, try to cover as much ground as possible through (explicit) knowledge (books, blogs, videos, you name it) but whenever I applied that to the real thing, turns out there was always something missing, that I didn’t plan for. (I’m assuming you value your time and try to maximize as much of it as possible) Now what I do: I still look for resources BUT those that cover the minimum required (THE FUNDAMENTALS) and build upon that knowledge through practice and better target research/reading.
I suppose the implication was that you read the docs as you build something — the proverbial learn on a "need-to-nerd-basis"
I'm the same, I can read 1,000 technical pages no problem and make you a great talk, but I'll remember nothing past a month (or 12...) if I don't actually use it.
The React docs are excellent. But many (if not most) other projects have woefully under-developed docs that offer confusion more than clarity. I wouldn't blame anyone for assuming that the docs are not the place to start for learning something new.
Nowadays if you face a tool with sparse official documentation or with total absence of it, it's probably better to find another tool or be prepared to learn from the source code.
For me React docs look really great, but I don't get a lot from them, even though I'd say I understand JS. OTOH Python docs usually look like crap, but I get a sense of understanding.
That has a lot to do with the underlying language actually. This is purely anecdotal but react was the first framework I tried to learn. It was hard for many reasons. One Angular internship and one big vue project later, it was no longer hard. Everything just fell in place. It just clicked. The secret? My JS skills got way better.
I guess (online) books speed up the learning, but I've learned all those techs by practice over a few months, official docs (mdn, nodejs docs, react docs, googling, github issues & stackoverflow) and IRC
The MDN and React docs are amazing! I consistently refer to them while working through the books for a deeper dive into the API's. I tend to have three MDN pages open at any given time.
JavaScript is very expressive and powerful language. Maybe hard to learn. The prototypal inheritence and 'this' were confusing to me and took much time to understand those.
Then I learnt that prototypal inheritance is a superset of ''class''ical inheritance [1] as well as this [2]. Hmm.
With Reflect, Proxy etc. you have great metaprogramming capabilities that make this language much powerful.
Still, there are some (many?) edge/corner cases and unfixable bugs (aka features) that the language is stuck with for the sake of backwards compatibility and developers have to learn these. (The most famous of these might be typeof null === "object")
When I look at the amount of features added to the language specification, sometimes it seems like it is going to become another incarnation of the C++ specification.
I still like its expressiveness and power, but if it becomes another C++ in future, I have to look somewhere else. (TypeScript maybe.)
I'm convinced that prototype object systems represent a poor set of requirements.
Those requirements are chosen because they lead to ease of implementation: prototype objects are the quickest and dirtiest way to enhance an interpreter such that programs can be written in it that are discernibly OOP-ish.
They don't represent a set of requirements that amount to a good OOP system.
> @s̮̦̩e̝͓c̮͔̞ṛ̖̖e̬̣̦t̸͉̥̳̼ It's been a while since I wrote this answer. My views have changed since I wrote it. Now, I believe that inheritance, both classical and prototypal, are bad and should be avoided at all costs. There's never a good reason to use inheritance. If you're writing object-oriented code then you should always prefer composition over inheritance. Even better, don't write object-oriented code. Embrace functional programming.
I hate being locked to single inheritance. Like, okay, we got the properties of foo; so that means we now absolutely cannot be a bar. It bugs me even if there is no plan to do that in the current program. By inheriting from foo, I'm enforcing the decision that this cannot be a bar, which could cause a problem to a future maintainer (maybe myself in six months).
Java has single inheritance, which sucks; but it has multiple inheritance of interfaces at least, and good luck doing any serious work in Java without that being involved. (That is also designed that way in order to pander to implementation ease and certain run-time efficiencies; but has been turned into fallacious arguments like "multiple inheritance is bad ... unless it's interface inheritance").
Oh, and one problem with this prototype business is that in fact it is single inheritance (in the typical incarnations, at least; am I invoking a strawman)? It seems inescapable that supporting multiple inheritance under the prototype paradigm requires that we make a single new object out of two or more existing objects. But if objects are effectively just bags of properties (a.k.a. hash tables) it does seem easily doable. Make new empty object, stuff with properties of all argument objects, season to taste, return.
> Sometimes opinions are great to get everyone on the same table
I think opinions generally achieve the opposite of that. That said, if you're sitting at the table where everybody believes in FP, you should wholeheartedly apply FP principles - or find another table. That's part of "do what makes sense, where it makes sense".
The really good thing about OOP though is that nobody really believes in it anymore. That opens up the opportunity to take some good ideas and insights and apply them undogmatically.
FP has good ideas and insights as well, but it's more difficult to separate those from the cargo cult surrounding it.
How would you write a component based architecture like React has? New API has moved away from the classical syntax where it would ‘extend’ React component but I assumed it was still doing prototypal inheritance. Isn’t it better for memory to have some sort of inheritance?
Honestly these things are all variations on a theme in JavaScript. The language is flexible enough that you can write code in many different ways and they all end up being equivalently powerful.
In JavaScript you have precise control over inheritance, you can specify your own algorithm for how class A inherits from classes B and C. It's a totally different beast to classical inheritance in Java that has such a bad reputation because it's such a straightjacket
If you find that shocking you would probably drop dead at seeing what Lisp programmers get up to with macros :)
Language flexibility doesn't obscure the readability of code. It enhances it. In a flexible language, unclear code is always programmer error, and programmer error is fixable. In an inflexible language, a lack of clarity can sometimes be unavoidable (e.g. java programmers forced to shoehorn everything into classes)
> If you find that shocking you would probably drop dead at seeing what Lisp programmers get up to with macros :)
I don't find it shocking, I think it's a sign of immaturity. Been there, done that.
> Language flexibility doesn't obscure the readability of code. It enhances it.
Given a language without any sorts of constraints, any program can and will be written in any conceivable style.
In design - not just programming language design - constraints are generally a good thing.
> In a flexible language, unclear code is always programmer error, and programmer error is fixable.
Virtually all errors are fixable in principle. In practice, there's a budget. Your clever and elegant but utterly idiosyncratic abstractions are costing me money in terms of getting people onboarded.
> In an inflexible language, a lack of clarity can sometimes be unavoidable (e.g. java programmers forced to shoehorn everything into classes)
This is not a bad trade-off at all.
A flexible language invites architecture astronauts to re-invent the concept of classes or modules over and over in slightly different ways. That's Javascript until ES6 and we're still suffering from it.
>> In design - not just programming language design - constraints are generally a good thing.
The best example of that in programming language design I have seen is the V programming language. (https://vlang.io)
No global variables, no null/undefined/nil/None/...
V is the only language I know in which variable shadowing is an error.
(Do you know any other language with this feature/constraint?)
And then I remember the handling of ''var''s in js and hoisting etc. ... sigh!
> Do you know any other language with this feature/constraint
gcc -Werror=shadow
Demo:
$ gcc -Werror=shadow -x c -
void foo(int x) { { int x; } }
[Ctrl-D][Enter]
<stdin>: In function ‘foo’:
<stdin>:1:25: error: declaration of ‘x’ shadows a parameter [-Werror=shadow]
<stdin>:1:14: note: shadowed declaration is here
cc1: some warnings being treated as errors
Yes, to hack up, so what? Non-prototype object systems can also be written simply and in a small footprint, and have a reasonably small description.
A prototype object system is barely one step above pretending that a hash table is an object.
2. It's powerful.
It's not expressive of OOP concepts and creates spaghetti code. All OOP is monkey patching: make this object like that one, but patch this.
3. It leads to smaller, less redundant code.
Because you're not properly specifying classes, which serve as an important guide to the structure of your program, and provide a locus of control.
We can achieve smaller and less redundant code by identifying every function that is only called once and manually inlining it, so there is no name that is redundantly mentioned two places in the program. That doesn't mean it's a good idea.
4. It's dynamic and hence it's better for dynamic languages.
This point is subtly fallacious. Dynamic languages also have non-prototype based object systems, which are also dynamic and good for those languages. There is good dynamic and there is bad dynamic.
Under prototype object, it's hard to do certain important dynamic things like redefine the method of a class such that all objects of that class (existing instances) use the new method.
Non-prototype objects systems in dynamic languages can easily support prototype-like mechanisms without those being the main mechanism of organization of OOP programs.
Failing that, in any dynamic language that gives you hash tables, you can ignore the fine OOP system and do prototypes with hashes.
They're most obviously a bad design because now any part of the code in your entire program can change the behaviour of any other bit of code. It means you can't understand code in isolation.
I would consider myself pretty close to an expert with JavaScript. I've been using it for 5 years professionally, currently use ES2020. Fairly familiar with Node 12, V8, etc. But I'm always worried about those situations where you dont know what you dont know. This might sound strange, but would anyone recommend any reading material or blogs for someone at my level?
I am not a full blown Javascript developer (backend developer here), but had been using JS and other frameworks for about 10 years now. I subscribed to Dan Abramav's "Just Javascript" [1] email. It is really good to read/follow and has one concept and idea explained well.
I think the sentiment of "you dont know what you dont know" is especially cumbersome with JS, since its usability is so much defined by its extensions (WebAPIs, runtimes etc.)
Reading into specs (ECMAScript[0], W3C[1]), some more approachable explanations[2] of them and some implementations[3, 4] of embedded engines seem to be my approach.
Eloquent is more of a fundamentals focused book, whereas Allongé is an excellent object-oriented foray, mixed with functional tidbits and examples. Allongé shows that you can get the best of both worlds, object and functional, by applying the right technique in the correct places.
One thing I've struggled with in JavaScript is choosing a more functional or OOP approach in certain situations. I can never tell if I should stick to one or the other. Allonge sounds like it'll really help me figure that out.
> One thing I've struggled with in JavaScript is choosing a more functional or OOP approach in certain situations
A couple key realizations made this much less of a "choice" for me (warning, my opinion):
1. Classes et al, are just a high level pattern which happens to be builtin... functions are far far more rudimentary.
2. If you use a high level pattern "just because you can" without considering the subjective cost vs benefit, it will be a poor fit on average.
What does this mean?
#1 Functions are not the opposites of classes, they are simpler, lower level abstractions which are more generalized - It should be thought of as the default.
#2 Like any pattern, OOP has a cognitive cost - When they don't fit a problem well, they merely obscure relationships between state and function; when they do fit a problem, they will minimize that cost and provide benefits that simplify other code.
If you don't immediately know that classes or prototypes fit the piece of code you are writing... just stick to functions, if later on you find that a collection of functions emerge with a common signature and persistent state being passed back and forth - you might have something that would benefit from a class, but you can simply change them into a class when it emerges. However if you do it preemptively you will probably be wrong and also make poor decisions about what the internal encapsulated state should be (which you want to minimize since you are obscuring it). It's ok to discover that something should be a class, attempting to make the choice up front is usually going to go wrong unless it's very obvious.
I think it's unfortunately a pretty natural path to start out not having an opinion of OOP and then potentially developing a distaste for it later on - not because it's inherently bad (it's probably the most generalized pattern and very useful); but because of it's integration into so many languages... I see it get abused by people all the time who just make a class by default for no apparent reason, which inevitably ends up as a bag of loosely associated state and arbitrary functions mutating one or more of those states. In such cases the class is of no benefit, and worse, it's obscuring all of the unrelated state mutations making it difficult to read and reason about.
The problem here is that this conversation is made complicated by the fact that plain objects in JavaScript are not what is really being talked about when people say the term OOP. So to clarify, stateful classes would be what I am talking about when I use that term. The foundation of OOP is based on tying state with functions in what are deemed "Objects". This implicitly makes all methods in an Object that depend on or modify an Object's internal state impure functions. And the purpose of most Objects methods are for the purposes of doing those things. Basically if you use stateful classes that encapsulate state and modify their own internal state with functions you are not doing functional programming. These two paradigms are in fact at odds and not compatible.
> This implicitly makes all methods in an Object that depend on or modify an Object's internal state impure functions
Note that you can have methods which do not depend on mutable state. In ES6 you can FREEZE objects, which you could do in the constructor. Freeze the object after having set its "instance variables". Now all methods of that object are "pure functions". So you can choose. Choose to create pure functions or impure.
Creating a new immutable instance really is equivalent to creating a set of immutable ('pure' if you like) functions.
How do you define object-oriented programming? From my perspective the very core of it is stateful objects with encapsulation and methods on those objects that pretty much always are not pure. If you just start treating objects like collections of functions, I don't really see how that's OOP. As far as I remember, it has been a little bit since I've used OOP everyday, pretty much every facet of the paradigm is centered around mutating state. You can certainly commingle OOP and functional code, but they simply aren't compatible paradigms.
I've been using JavaScript professionally for about 12 years.
You're going to have to look for talks and really technical posts. Consider whitepapers and source code for JavaScript engines at this point. You'll probably want to start reading up on the things attached to JavaScript, rather than the language itself. Browser rendering, event loop, V8 things, garbage collection, etc.
I was lucky enough to see this live - https://v8.dev/blog/elements-kinds - but I recommend watching and reading for anyone. Half because is pretty interesting and accessible at the same time. And half because you might use it .
I definitely wouldn't consider the first video 'advanced' material (an excellent talk btw), JavaScript event loop is something beginners should know about and intermediate developers know very well.
Ah, but do they know where in the event loop, for example, "microtasks" get executed as opposed to... I forget.. tasks? In other words, how execution of promises is different from the execution of setTimeout?
Have you ever read through this annotated ES5 spec? Even annotated it's still pretty dense, but it's a nice way to both dive deeper into the language and as a 'minimap' to guide you through the parts you have yet to totally master. It definitely helped me level up more.
if you can't find something you didn't already know in the free book series "you don't know javascript" then I'd imagine you might not have any gaps in your knowledge. (at least for 99% of it)
(you can buy a hard copy of it if you want but it's open source)
Some of the TC39 proposals might be worth looking at. The ES spec too.
If you really want to go all out, you could write a simple JS interpreter. Probably don't want to go full spec compliant but you could implement a decent subset. Especially if you skip the parsing step with Acorn https://github.com/acornjs/acorn
Big scare quotes there, you can't really 'prove' much in typescript. Don't get me wrong, it's a nice type system they've tacked on to JS, but it's far and away from proofs of correctness. At best, it's an optional type system with escape hatches.
You can only 'prove' what you expect from your design. This works in most cases and saves a lot of guesswork on big, unfamiliar projects. It's not an integral part of JS though, so I wouldn't recommend learning it as a foundation.
read "you don't know JS" series of books, also second edition https://github.com/getify/You-Dont-Know-JS I find the workshops very helpful as well, which I've watched through my oreilly membership don't know if you can find them elsewhere, I would suggest combine this with reading the specs.
on edit: one reason the specs are not enough is generally specs will tell you what needs to be implemented but a good book, like these ones, will tell you how it has been implemented or what the spec implies for implementation and what all that will mean for you as a user of the language.
> But I'm always worried about those situations where you dont know what you dont know. This might sound strange, but would anyone recommend any reading material or blogs for someone at my level?
It's not very clear what you are asking, neither what's your background. In your situation I wouldn't spend more time learning stuff about JavaScript, I would just improve my skills in software engineering (design patterns, code quality, refactoring, etc) and diversify my knowledge (learn other languages (python, go, or some FP language to learn something really different); databases and SQL; web servers and REST; etc).
Not sure how it holds up, but Secrets of the Javascript Ninja was the book I read when I felt like that, and it significantly helped me understand a few concepts I had struggled with. By John Resig (created jQuery). But it's a few years old now, so likely won't cover much if any ES6+ stuff. But I'd bet the concept stuff is still very valid.
Also the You Don't Know JS series. And Elliot's Programming Javascript Applications.
I don't know you, so I don't know if this applies or not, but be careful not to fall into the "expert beginner" trap (i.e. Dunning Kruger). Your first sentence starts to feel that way, but the fact you're asking for more resources and aware there are things you don't know are good signs. Always keep learning, the rabbit hole goes ever deeper.
humble opinion: N years of using any language won't make you an expert.
There's knowledge about how to express certain patterns in a given language, more like an application design expertise. There's knowledge and familiarity with the APIs. And then there's the deep language knowledge, the one that pretty much only someone implementing a language VM, parser, compiler and other tools may acquire with time. Also, there are a lot of specifics about every particular JS implementation.
Great read, though his writing style is less intuitive if you are fairly new to JavaScript and trying to grasp some of its concepts. For example, in his reduce function [0] example, he names his variable "current" to bind the accumulated value the reduce function is going to eventually return. That is a totally fair name, but I don't know if it really "clicks" if you were reading over this for the first time. I think it would be faster to grasp the reduce function's purpose if it was simply named "accumulated" or something alike, especially when this snippet is advertising the idea of higher order functions and callbacks.
Little things like this I am nit-picky about, but overall, great book.
> This much anticipated and thoroughly revised third edition of Eloquent JavaScript dives deep into the JavaScript language to show you how to write beautiful, effective code. It has been updated to reflect the current state of Java¬Script and web browsers and includes brand-new material on features like class notation, arrow functions, iterators, async functions, template strings, and block scope. A host of new exercises have also been added to test your skills and keep you on track.
Does anyone have a book recommendation (free or paid) that is modern and up-to-date, preferably regarding typescript, that talks about best practices and patterns for large-scale project design and code structure?
For example, a book that could go into details of code practices at companies like Airbnb, Facebook, or Google.
Typescript is relatively new, and I think a lot of those companies are still trying new things and experimenting with what works. I expect that we will see more refined content and books about TS-at-scale in the near future though.
However, for those looking for a great way to learn Typescript from a beginner's perspective I can fully recommend Execute Program[1].
At the speed of javascript though, it's pretty mature now. When I tried searching on Amazon I was getting back $30+ dollar ebooks with chapters on how to use Gulp (superseded by webpack or babel)...
> patterns for large-scale project design and code structure
I would be particularly interested in this. The OP has a chapter on "Program Structure" but it seems like more a toolbox of language constructs.
It would be nice to see a book that went through a few archetypes of common JavaScript programs (command-line script, daemon, enhanced webpage, single-page app) and gave a basic blueprint for what parts are needed and how they interact.
Not quite what you're asking for, but I really liked this book since it was beyond introductory material and had concrete examples of what and why to do things:
A project in TypeScript is not much different from one in JavaScript structure wise. The biggest difference might be the explicit work on types and modeling your problem to make good use of composite types. In the source code you'll have some type definitions where implementation and usage sit close to each other (to enforce a local implementation), and others where a type is more like a serializable DTO (data transfer object) between different domains and seen more global throughout your application. You'll get a feeling when mapped types should alter a type or when a local type definition might be better (TS is structurally typed for a reason).
Domain modeling can feel close to "type driven modeling" here. A good book in that regard is "Domain Modeling Made Functional"[0]. I see types and a functional paradigm closely related, but keep in mind that this is just one approach in your toolbox... there might be the case where a GoF OOP pattern works good as well[1]. I think it's also important not to try to trick the TS compiler into something, but rather to work with it. Keep in mind that the TS dev team is giving you a lot of freedom by not striving for a provable correct type system[2].
To really take advantage of TypeScript I think it's good to know where a type system is coming from, what it is that it's trying to solve and how it is doing that. I think it's helpful to have a look into other languages with a "strong" type system (Haskell[3], OCaml, rust) and see how they are doing it. Then you may get to see how Haskells phantom types will conflict with TypeScripts type inference, and OCamls type inference seems to work in fascinating ways compared to TypeScript. After working through the advanced types[4] in TypeScript it's good to understand what a "good abstraction" in case of a type system is and what isn't... this is when you discover the similarities to other languages through the common language of abstract mathematics (and abstract data types). In every program you'll encounter effects and monads are quite helpful to work with them, this is were a sound type system can really shine.
I feel with every JS/TS project you will build a lot of the projects toolchain yourself and you kind of need to discover what fits best. It's good to be able to catch possible bugs early with the TS compiler, quicktype[5] can help you in building some typed contracts to other projects.
A separation into packages with lerna[6] should encourage a good separation into packages and is seen in a lot of open source projects. Speaking of, reading into good open source packages will be a mandatory way to go in order to learn more.
Unfortunately not. DDD is a design concept on how to match the business domain in source code - the design step is language independent and the practical implementation is very business dependent. I'm also keen to find a good practical reference, but can also understand why there might never be one. The book above on F# is very approachable, as F# in the predecessor of TS and the first half of the book is even language independent. Learning some SOA (service oriented architecture) terminology will be of some help as well.
I highly encourage you to not solely stick around JS/TS for patterns. For me, JS/TS is the "most" multi-paradigm language in usage to date, thus is not one of those languages that needs to be written in a certain way. Other languages can give you patterns more clearly and those are for the most parts adaptable to JS/TS. Haskell made it click for me on how to model with types, Elixir has the interesting concurrency/resilience pattern with supervisors etc... There are also good JS libraries whose usage still feels like programming and less "using a framework"-like - RxJS has an interesting approach for events/subscriptions and I feel like redux-saga showed me a very good use case for generators.
I have avoided yield() and generators like the plague because they're hard to read and I've never seen them used except in examples explaining how they work. Yield feels like recursion - a neat trick for some corner cases but generally unnecessary.
JavaScript syntax for generators is clunky no doubt. But they let you do some things more naturally than anything else in JavaScript. They keep track of state "implicitly" you don't have to do an assignment to 'save a state", you just yield and your state is remembered.
I found generators useful for implementing my home-brew parsers. Parsers must try out all possible combinations of possible syntactic elements before they can say that parse failed. Generators are a good tool for that
The basic idea is that a generator yields one potential parse of a section of input-string. The caller continues checking the rest of the string but if it fails to find all expected syntactic elements it will go back to the generator basically asking it: Your previous suggestion did not work out, can you give me another possibility?
This is how async/await is implemented. I think 'await' is almost just a synonym for yield. I didn't invent that part. I just made a faster, better encapsulated, promise free version.
So generators are used here because of the natural way of calling “next” and yielding a result.
How would this work for say, an XMLHttpRequest? Since you have to next into callbacks there I don’t think yield travels the function boundary...so you abuse next instead?
Wow I haven't used that directly in a long time. Ideally you would wrap it to be in continuation passing style.
This would look something like:
function fetchUrl(url,done){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 400)) {
done(null,xhr.responseText);
}else{
done(new Error("something went wrong"))
}
}
}
xhr.open('GET', url, true);
xhr.send(null);
}
Then you could do:
let response=yield fetchUrl('http://example.com',next);
edit: In case this doesn't really answer the question: If you really don't want to wrap, it would work inline too. It would just be harder to read and follow:
var someFunction =casync(function*(url,next){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 400)) {
next(null,xhr.responseText);
}else{
next(new Error("something went wrong"))
}
}
}
xhr.open('GET', url, true);
var response = yield xhr.send(null);
...
});
As someone who hasn’t done much JavaScript since AngularJS in 2014/2015, what is the current state of JS like?
I see there’s Angular (not AngularJS that I worked with), React, and some other frameworks. I see there are all kinds of bundlers and plug ins for these things.
When I was doing AngularJS, I’d just link to a few dependencies manually from a CDN. Looks like now there’s a bunch more complexity and package management for front end dependencies.
It feels like FAR more complexity, but I’m not sure what has been gained. I also don’t know that much, so would love to learn perspectives here from people actively developing in this space.
If you're looking for a fully featured framework, Angular is a joy to work with. React is great too, but the configuration overhead is enormous due to the fact that it's mainly a view library. I realize you are pining for the days when you just pasted a CDN link in your index.html, but while those use cases still exist, for the most part users are demanding more native-like web experiences, which requires a bit more complexity.
One of the main strengths (and according to some, weakness) of Angular is that it has everything you might need to create a full featured SPA out of the box, and it's all tightly orchestrated by the Angular CLI. Creating a component or a service is a simple command, and many third party packages leverage the CLI (Angular Schematics) to install and configure themselves in your codebase. Core packages--such as such as forms, router, angular material--are all high quality (by Google), updated together, and work cohesively with each other. That means updating even major versions of Angular is an easy `ng update` command. For me, the minimal configuration overhead is a BFD, as I plain hate that stuff.
The fact that Typescript has been a first class citizen of Angular from its outset makes development pretty enjoyable. I'm so used to exploring APIs using intellisense, leveraging types to figure out what data types can be passed in functions, relying heavily on auto-complete/auto-import to pick up my pieces and finish typing a word for me and importing the corresponding library while I keep going.
Granted, there is a significant learning curve. But once you get over the initial learning curve, you become incredibly productive. Arguably, the learning curve in other frameworks is worse, given that you have to research what libraries to use (e.g., which forms library, with its own set of conventions), configure it, and make sure it plays nice with the other patchwork of libraries.
I initially loved React, but i eventually feel out of love due to the complex tooling required to use React (e.g. configuring webpack, evaluating data store options, evaluating form options)
If you're interested in a fresh, lighter, framework-free approach, have a look at svelte: https://svelte.dev/ I'm using it on a current project and loving it so far.
Can anyone recommend reading for the web-related Javascript "API" so that when Javascript is used in the form of generated code, e.g., through asm.js, the "API" can be used by the "generating program" without the need to learn all of Javascript.
Essentially so you could do HTML/CSS/some-other-language (using asm.js, emscripten, or some similar technology) instead of HTML/CSS/JS.
No because this is an introduction to programming using JavaScript. A quick look at the table of contents shows Part 1 teaches basic OOP, Part 2 teaches basic client side web development, and Part 3 teaches basic server side development using Node. Having read the 2nd edition of this book, I can assure that if you can explain what any of the 3 main topics described in this book are in a few sentences, then you have advanced well beyond this book being useful.
The chapters from 13 on are great for anyone as an intro to how JS interacts with the browser.
I agree with the other commenters that the early chapters would probably move a little slow for an experience programmer, though it is beautifully written and the interactive snippets are great, so you might still enjoy it if you don't mind skimming. Or if you know some languages but only have a few years of experience I would say beginner intros to new languages are still good. Eloquent JavaScript is a really nice overview of clean programming style in JS as well as the language itself.
Definitely NOT recommended for absolute beginners. I tried reading this as one of my first programming books and it confused the hell out of me. There are much better introductory books/courses - my recommendation is "Watch and Code - Practical Javascript" if you are an absolute beginner and want to learn javascript.
Eloquent Javascript is a good book now that I know more about Javascript, but please NEVER EVER recommend it as the first book for an absolute beginner.
Have to agree with this. I was just reading through to try to figure out its pitch, and was struck by this (early on): "To create a value, you must merely invoke its name. This is convenient. You don’t have to gather building material for your values or pay for them. You just call for one, and whoosh, you have it"
I mean, that's totally correct, but that's paragraph 7. It's way too abstract for a beginner to understand - and usually, if a beginner is getting lost in the first few pages, they're unlikely to make progress in the book (even though they probably could in this case, by skipping ahead a bit).
I skimmed through head first, it seems pretty good but similar to a lot of other books. The watch and code course is different and I just think it’s so on point for the absolute beginner, or at least how I like to learn.
With 20/20 hindsight, what I wish I had done is read through or watch one or two courses without any pressure, just get familiar with the topic, and don’t worry if I don’t understand things.
things start clicking into place after you’re exposed to this stuff a few times. My mistake was that I wanted to understand everything and didn’t want to skip ahead if I didn’t.
From my personal experience, I was not ready for this book when I was a beginner at took a stab at reading it. I had written in JavaScript before and stumbled upon this book through the Internet, and it demotivated the life out of me.
I am now about a year and a half of being deeper into the language, and I have finally picked the book back up again.
I always skip to the async part of JS text because explaining it is a bit like handing a shotgun to a five year old. I think the folks over at risingstack have the best explanations, IMHO.
I'm surprised they attempted timeouts in promises with so little text, that's actually pretty dangerous pattern because it glosses over the complexity in actually stopping an in-flight promise. It is VERY easy to end up with hundreds of thousands of unresolved promises with their pattern. Dangerous!
There is a great repo on this issue.... aand I can't for the life of me find it. Basically there's a github project that uses generators and passes an atom down through the call stack to ensure everything below the race promise is aware that it is being halted. And even that doesn't handle all the nuances of this pattern.
And if anyone knows what github repo I'm talking about, I'll give you ... 50 DKP?
I used to use more "Promises" but now I mostly code with plain callbacks if possible. It is just simpler, less thinking needed. I spend that thinking-budget on other things.
One thing that is tricky with async is that nobody tells you if the async function never does what it should. I wish they would add some more built-in support for that in the next JS version.
Promises hold promise (pun intended) but they are a bit too complicated for my brain.
I'm not sure it's much less code. Especially that async/await is integrated into the language now. It's less state, less corner cases, more encapsulation and better performance.
I'm thinking of trying (if I have time) to build a babel transpiler plug-in so you could use it with keywords like async/await instead of explicitly wrapping generator functions. I think the syntax would end up very simple.
In sync programming if your function does the wrong thing you typically get an error thrown or you get a result which you check for its correctness.
But when you call an async-function that is supposed to do something like say write to a file or database maybe there is an error which makes it never do its job, and never call the callback you gave it. But the rest of your program just hums along happily. There is no error. The error does not "happen" but the error is that "something did NOT happen". And when something does not happen you don't get an error or notification saying that something did not happen.
You run your program but expected results do not show up in database. But you don't know why, because the problem is that some of your async functions did NOT call something they should have called.
It's hard to detect that something does not happen.
Some kind of built-in support for callback-timeouts might alleviate this problem.
What are you talking about? if you're async operation fails then your callback should always still be called but just with an error message in the second parameter typically. And what are you doing still giving call backs to async functions? Why are you not using promises?
I think previous poster is talking about a bug where the promise is never resolve nor rejected. So it just hangs out there, unresolved, forever.
I don't think using explicit callbacks helps, though, which has the same potential issue (worse really, since you're probably handling callbacks directly more often, depending on the patterns you use).
Right. Except I was able to experiment with a wrapper-function which set up a timeout on the callback which threw an error if the callback was not called within a set interval of time.
It helped to detect some flaws in my program.
A similar thing could no doubt be done with promises. But I think the best solution would be if there was a built-in facility to detect callbacks that were not called within a required or default time interval.
Eventually I stopped using the timeout wrapper, it didn't help very much, but made the code more complex. More but easier to understand code is often my preferred choice.
Whereas if language itself offers built-in facilities then fine since they are more likely to be bugfree than my own code.
Javascript code doesn't just stop executing for no reason, if the callback needs to stop executing, it should reject the promise or throw an error. Or resolve with an error value. That's like saying "in sync programming, if you don't check for error conditions, your code continues humming along happily just the same".
If there is an error when reading a file or accessing a database, unless the file or database API is horrendously designed, it will reject the promise or throw.
> Javascript code doesn't just stop executing for no reason,
I would say it stops unless there is something keeping it running.
Think about your single-page-web-app. When you click on some widget on it a click-handler triggers and executes that code. But then it stops. When the user doesn't interact with your web-app no JavaScript is typically executing, unless you have set up a repeating polling loop with setInterval().
The scenario you described is a classic one and I really don't think it's as problematic as you may think. I had to reread it because it sounded too trivial. How about just throwing an error when the async function fails to write to the db?
>maybe there is an error which makes it never do its job
You can throw an error regardless of the reason why it failed to do its job. If the write to the db does not success, you can throw an error.
You are supposed to call fs.write() etc. But you do it only under certain logical conditions. Those logical conditions do not arise like you would expect because of logic errors elsewhere in your code.
So your async function never calls fs.write() even though it was your intention that it should. Is that an error? Definitely, the file was never written to, it now has wrong content. But the problem is, as you run your program you do not get any error thrown at you, therefore you don't even know there is a problem. Later on you may, or may not, realize that the content of the file is wrong. And then it's hard to say what caused that error.
What "caused something not to happen" is a difficult question to answer because you can't pinpoint the exact location in time and code where it did not happen. Why? Because it did not happen anywhere, ever :-)
Btw this same issue exhibits in python with threads. If you spawn an async computation in a thread and an uncaught error is raised, the thread disappears silently, leaving you with a callback that’s never called or a future that’s never resolved.
But I assume in a thread-based language like Java all asynchronicity happens due to threads. Then from the programmers' point of view method-calls always either return a result or throw an error. They don't just silently stop executing
Funny, I now treat everything as a promise: all my functions are async because it keeps the interface simpler: if they don't return a promise, they are just a normal function, no harm, no foul.
I see no reason to use callbacks, unless the NodeJS module dev didn't implement promises. And even then I write a wrapper. I'm glad to see later versions of Node include promisified versions of things like File IO.
> glad to see later versions of Node include promisified versions of things like File IO.
I agree. They are easier to use. But they require more effort to write. Promises are easier to use than create. Maybe they are the direction in which public APIs will go but I do find they take extra effort to write, compared to callbacks
I think you're going to point out that I'm about to demonstrate non-JavaScript nuances, but here are issues I've encountered:
Let's take a great of example of where promises are used most often: AJAX. If the endpoint isn't RESTful and there is state on the other end, cancelling a promise requires updating the entire module of the new state. There can be multiple reasons for cancelling, and the code needs to be aware of what is happening beyond a simple timeout.
Same thing goes for USB devices (via libusb+ffi) and serial-ports (via serialport). In flight requests can disturb state if cancelled, and it makes the programming very complex to just time-out.
One could argue AJAX and hardware programming are outside the domain of JavaScript, but I wouldn't.
I guess it is more than a "nuance", it is the observance that cancelling an asynchronous operation in general can have unintended consequences if not handled correctly ... beyond memory leaks from unresolved promises.
Here are the things that I really really hate about javascript:
I find javascript really hard and annoying, even if I have enough experience with JS that lets me build a basic react framework, I still find it hard to use.
On top of that, getting javascript jobs is harder compared to other programming languages. IE: you need 7 years of experience for a company at the same level where they only need 1 year of IOS/Android experience.
You always have to be keep up to date. The popular libraries that you can use changes so fast, and sometimes they don't even work.
Javascript gets a lot of disrespect from beginner engineers. Something about doing frontend work, isn't hard and it isn't software engineering in their perspective
There are so too many ways to do the same thing, unlike something like lets say golang
You always have to learn more than javascript to compete with other javascript developers. IE: dev ops, backend, database, sre, ux design
So from your perspective, what are the languages (besides iOS/Android) that you believe to be far more ideal when it comes to job prospects, quality of language and ecosystem, and developer happiness? I don't really disagree with most of what you said, but they feel like complaints that I'll hear about any language from its professionals (i.e. familiarity breeds contempt).
(I definitely agree with you about the disrespect JS gets from those who don't grok frontend work. And the fundamental annoyances baked in JS from the start)
I think most everyone agrees JS is an outlier when it comes to the speed of breaking changes and obsolescence, but IMHO that is nearly inextricable from JS being the most widely-adopted language, compatible with the widest variety of end-user devices and applications, reaching by far the most humans across the world. To put it another way, you could easily learn and become proficient in COBOL. There's currently a bigger demand than ever for young blood, and there's presumably great career rewards (if not in salary, in benefits, timeoff, and pension funds), and the language and end-user application is extremely stable.
And of course there are plenty of disadvantages (higher chance of landing somewhere that is not SF or NY, if those cities happen to be your home). Do the benefits of COBOL, especially the ones that line up with Javascript's weakness, hypothetically meet your ideal of a developer job?
>IE: you need 7 years of experience for a company at the same level where they only need 1 year of IOS/Android experience.
Job requirements for iOS & Android might say one thing, but you'll still be competing with people who have way more experience than that, unless the company behind the listing refuses to budge on compensation and is up-front about it.
One thing that iOS really has going for it is that (IMO) it suffers from ageism far less than other SWE verticals do. I'm having trouble with putting the reasons for why I think this is the case into succinct words, but I would say that the primary reason is that iOS knowledge & experience gained while working is, in most cases, additive. The only exceptions are when things are deprecated, but from what I've seen, this usually just involves API signature changes. The core framework has stayed the same, and SwiftUI is going to be the first significant change. You're also forced to constantly learn new things every year, because you're forced to update, and forced to accommodate new screen dimensions with designs.
The downside of this is that it can be extremely difficult to break in as a beginner without doing an internship at a company that can afford interns. You are competing with people who have anywhere from 3-12 years of experience. Or you're competing with people who did the aforementioned internships and did not receive an offer.
Your comment got 5 upvotes and 8 downvotes so far. The maximum score it reached was 2. It might seem odd how 2 turned into 20 in your mind, but actually it's not unusual at all. Perceptions of other people are routinely off by an order of magnitude on HN (and, I assume, elsewhere on the internet). That's the main reason why moderating a forum like this is so hard.
What do you mean by "right side comments"? I wonder if there's something in HN's UI that is misleading. (Or perhaps you're using a third party extension of some sort?)
> right side of my name is the comments beneath my comment
Do you mean the number like [+11] that shows up after you've collapsed a subthread? If you click it, do the comments beneath your comment reappear and the number goes away?
Edit: I'm pretty sure that is the confusion, because it's the second time in a few weeks that this has come up. I've changed the "collapsed" indicator to say "[5 more]" instead of "[+5]". Hopefully that will solve the problem. The strange thing is that it took almost 4 years to hear about this.
I'm sure you will be downvoted as hell because you're critic and not upbeat, HN just likes everyone saying good words all the time, i.e. stay politically positive. However I strongly believe critic is more meaningful most of the time as long as it does not have bad intention, thus I upvote you.
JS is indeed hard, learning vuejs for the sake of 'it's simpler than react' right now.
Client dev was always hard. People just mistake that for Javascript because they don't have any experience building clients.
For example, I'd say JS/React is vastly easier than learning Cocoa/UIKit. Writing GUI code that runs on N user devices is harder than writing headless code running on a single server.
Btw, if they're getting downvoted, it's because "oh, Javascript is in the title? time for me to complain about it like people do in every JS-related HN thread!" is a tired HN comment.
I disagree. Headless code on a single server can still be very difficult. For instance, nginx, mariadb, etc, which allow the frontend to function well, are difficult to write. You have to deal with multiple threads, search algorithms, handling tcp/udp requests, and optimizing all of that so it isn't dead slow. Whereas writing GUI in JS/React involves less "computer science" complexity and more compatibility complexity-dealing with things like, what is the screen-size, the locale, etc.
On the note of the HN's perceived hatred of JS, I think its because Javascript has tried to do too many things. Despite its quirks I like Javascript in the context of the web browser, but what I dislike it that it exists in applications and on the server side. The Atom editor should not take up 200 MB and take forever to boot. But it does because instead of taking the time (like sublime text) to write a rockstar system code, they instead used electron. The feeling I get sometimes is that JS developers want to program the same way they do in the browser, everywhere.
Are there easy ways to write GUIs without Electron that still can use HTML+CSS for layout and design that allow you to have an identical experience on Windows/MacOS/Linux? I think this is the main thing webdev-land people like (myself included). Also, there are so many npm libraries to handle stuff for you that staying within that ecosystem is enticing.
My point was more along the lines of the code bloat that comes from essentially emulating a web browser on system, when in reality you can write much faster code in C/C++ or even C#/Java. But, GUI design for applications can be a nightmare, with QT on the one hand versus fragmented Cocoa/Windows Whatever in C#.
I think Electron was the webdev community's response to this, and we really haven't gotten one on the app/systems developer side besides QT.
Or to rephrase, using Electron to "emulate" a web browser is cross-platform from the perspective of the electron user, while most other gui-ing solutions in C/C++, are not necessarily cross-platform, and therefore this leads to different set of challenges.
For those interested--Besides this book, my current learning plan includes: Javascript 30 by WesBos Exploring ES6 [http://exploringjs.com/es6/] Learning React-2nd Edition on O'Reilly Learning The Beginners Guide to React on Egghead Data Structures and Algorithms in JavaScript on Egghead.
I also used Kent C. Dodds' excellent "JavaScript to Know for React" article as an outline.